OpenJDK Project Loom: JVM Threads With Light-Weight Concurrency

Note: Java Project Loom is under active development. The only supported OS platforms are Mac and Linux on x86-64. The tested garbage collector (GC) is G1 and parallel.

Today, as a developer we have a choice when we’re writing big applications. We can write simple synchronous blocking code that easy to profile but it may throughput or scalability issues because of the number of threads that our OS support is much less than the number of concurrent connections our application requirements.

On the other hand, we will make the choice and use an asynchronous framework for light-weight concurrency. Most of Java developers like me use that helps us to write code in a reactive manner.

Project Loom (Light-weight Concurrency Framework)

Project Loom is another Java concurrency framework started at Oracle. The purpose of Project Loom is to support easy-to-use, high-throughput more granular concurrency, and new programming models for Java platform. Project Loom brings the almost same functionality internally as goroutines bring in golang language. It allows Java developers to write a scaleable application without much knowledge about reactive programming. Loom makes easier to debug, profile, and maintain concurrent applications meeting our application requirements.

Recently, I published an article on Java multithreading “How I managed to create thousands of threads on the server, a thread for every single device“. So, in this article, I’ll try to implement the same example with Project Loom and improve my threading model.

Now, if you see my article on java multithreading then you maybe remember that in the first step we try to open up a ServerSocket inside the DeviceListenerRunnable class.

Here’s the implementation of DeviceListenerRunnable class.

public class DeviceListenerRunnable implements Runnable {

    private final int portNumber;
    private final ServerSocket serverSocket;
    private final IConnectionEventArgs connectionEventArgs;

    public DeviceListenerRunnable(int portNumber, IConnectionEventArgs connectionEventArgs) {
        this.portNumber = portNumber;
        this.connectionEventArgs = connectionEventArgs;
        this.serverSocket = new ServerSocket(portNumber);

    public void run() {
        Socket socket;
        while (!Thread.currentThread().isInterrupted()) {
            try {
                socket = serverSocket.accept();
                connectionEventArgs.onDeviceConnected(socket, socket.getRemoteSocketAddress().toString());
                if (!socket.isClosed())
                    Fiber.schedule(new ReceiverRunnable(socket, connectionEventArgs)); // 1
            } catch (Exception ignored) {

I’m not going in the detail of above class because I already did that in my previous article. So the only part that changed here is the thread scheduling model. The logic inside the run method remains the same.

Now if you look at the above code where I’m passing the ReceiverRunnable instance to the Fiber.Schedule method. Well, ReceiverRunnable is nothing just a class which implements the Runnable interface. Instead of handling concurrency ourselves we just pass our Runnable class instance to Fiber.Schedule. Internally, Fiber.Schedule method will handle the concurrency for us in an efficient manner.

What is Fiber in Project Loom

According to Project Loom Fiber is a ” lightweight or user-mode thread, scheduled by Java virtual machine, not by the operating system”. It makes developers use simple abstraction but with better performance and lower footprint. The Fiber threads are more light-weight in terms of memory and almost zero overhead in terms of task switching.

Now we can say that the Fiber thread in Project Loom code like sync but work like async in the sense that your code looks locking, but from the perspective of an operating system, no kernel thread is actually blocked, and all the IO behind the scene is synchronous.

The following shows the equation of Fiber thread.

Fiber Thread = Continuation + Scheduler

Implementation of ReceiverRunnable

The ReceiverRunnable basically processing all the incoming data from the connecting sockets and send data back to caller class via IConnectionEventArgs. Every client connected to this application has its own instance of this class.

public class ReceiverRunnable implements Runnable {

    private final Closeable closeable;
    private final IConnectionEventArgs connectionEventArgs;

    public ReceiverRunnable(Closeable closeable, IConnectionEventArgs connectionEventArgs){
        this.closeable = closeable;
        this.connectionEventArgs = connectionEventArgs;

    public void run() {
        if (closeable instanceof Socket) {
            Socket socket = (Socket) closeable;
            while (!socket.isClosed() && !currentThread().isInterrupted()) {
                String info = socket.getRemoteSocketAddress().toString();
                try {
                    byte[] data = handleTcp(socket);
                    connectionEventArgs.onDataReceived(info, socket, data);
                } catch (IOException e) {
                    connectionEventArgs.onDeviceDisconnected(info, e);
                    try {
                    } catch (Exception ignored) {

    private byte[] handleTcp(Socket socket) throws IOException {
        // Logic for reading the input stream

The only thing change here from my previous article is the only ReceiverRunnable class implements Runnable interface instead of Thread class. Well, that’s because our Fiber.Schedule class takes the instance of Runnable instance.

Comparison of Fiber Threading vs Simple Threading Model

Now, if I run my program without using Project Loom Fiber thread and connect almost a thousand client with my application. The stats of the java process look like this.

Without Java Project Loom Threading Model

In the above stats, you see java process take 90% CPU usage of Linux based server. Now If I run my service with Project Loom threading model then the stats would like this.

Java Project Loom threading model

You can clearly see the difference, with the Fiber threading model java process only uses the 6% usage when almost a thousand client connected to my service. All of those clients sending data every 30 seconds.

Download Java Project Loom

Ron Pressler the project lead announced that the project will be available publically for download. You can download the project from this link.

Alright, guys, I have tried to share some of the lessons that I learned to work with Java Project Loom. I hope it helps someone and makes their life a little bit easier when working with Java multithreading. If you like this post don’t forget to hit the ♥️ button below.

More Resources

Thank you for being here and keep reading…

1 Comment

Write A Comment