Java Project Loom: Understand the new Java concurrency model

Project Loom aims to drastically reduce the effort of writing, maintaining, and observing high-throughput concurrent applications that make the best use of available hardware. My code is posted on loom-lab in case other people want to verify my conclusions. This is a learning project, and I am learning… I maintain some skepticism, as the research typically shows a poorly scaled system, which is transformed into a lock avoidance model, then shown to be better. I have yet to see one which unleashes some experienced developers to analyze the synchronization behavior of the system, transform it for scalability, then measure the result.

java project loom

It used to be simply a function that just blocks your current thread so that it still exists on your operating system. However, it no longer runs, so it will be woken up by your operating system. A new version that takes advantage of virtual threads, notice that if you’re currently running a virtual thread, a different piece of code is run. This is a main function that calls foo, then foo calls bar.

Not the answer you’re looking for? Browse other questions tagged javaproject-loom or ask your own question.

Note that the part that changed is only the thread scheduling part; the logic inside the thread remains the same. What we need is a sweet spot as mentioned in the diagram above (the green dot), where we get web scale with minimal complexity in the application. But first, let’s see how the current one task per thread model works. The problem with real applications is them doing silly things, like calling databases, working with the file system, executing REST calls or talking to some sort of queue/stream. We can achieve the same functionality with structured concurrency using the code below.

java project loom

It has obvious drawbacks, as all your code now becomes Async, with ugly callbacks, meaningless stack traces, and therefore hard to maintain and to reason about. We very much look forward to our collective experience and feedback from applications. Our focus currently is to make sure that you are enabled to begin experimenting on your own. If you encounter specific issues in your own early experiments with Virtual Threads, please report them to the corresponding project. Virtual Threads impact not only Spring Framework but all surrounding integrations, such as database drivers, messaging systems, HTTP clients, and many more.

The InfoQ Newsletter

Project Loom has made it into the JDK through JEP 425. It’s available since Java 19 in September 2022 as a preview feature. Its goal is to dramatically reduce the effort of writing, maintaining, and observing high-throughput concurrent applications. “Leveraging that model, you could build apps that, in terms of utilizing resources, are on par with an asynchronous or reactive programming model,” he said. “It’s interesting to see these competing models, and in general just getting improvements in the existing system.” “The principle for structured concurrency is quite straightforward — when there is sequential code that splits into concurrent flows, they must join back in the same code unit,” Garcia-Ribeyro said.

After switching to Project Loom as an experiment, they realized that the garbage collection was doing way more work. The stack traces were actually so deep under normal load, that it didn’t really bring that much value. Concurrent https://www.globalcloudteam.com/ applications, those serving multiple independent application actions simultaneously, are the bread and butter of Java server-side programming. Do we have such frameworks and what problems and limitations can we reach here?

Project Loom could help Java keep pace with web apps

You can also create a ThreadFactory if you need it in some API, but this ThreadFactory just creates virtual threads. You might think that it’s actually fantastic because you’re handling more load. It also may mean that you are overloading your database, or you are overloading another service, and you haven’t changed much. You just changed a single line that changes the way threads are created rather than platform, then you move to the virtual threads. Suddenly, you have to rely on these low level CountDownLatches, semaphores, and so on.

  • Today with Java 19 getting closer to release, the project has delivered the two features discussed above.
  • If a virtual thread is blocked due to a delay by an I/O task, it still won’t block the thread as the virtual threads can be managed by the application instead of the operating system.
  • This helps to avoid issues like thread leaking and cancellation delays.
  • Currently reactive programming paradigms are often used to solve performance problems, not because they fit the problem.
  • This can streamline error handling and cancellation, improve reliability, and enhance observability.

My expectation I could speed things up with Virtual Threads was a misunderstanding of how Virtual Threads are optimized. Means that Virtual Threads are not going to give me the performance boost I was hoping for in this use case… I am experimenting with Virtual Threads in my loom-lab project, and wanted to see if Virtual Threads are faster than Platform Threads when doing a parallel stream, but it actually seems slower. The question goes to the heart of Project Loom design and implementation, and whether the project has been able to speed up the performance of Java Parallel Streams or not. The question is not about bench-marking, it is about intent of Project Loom. We get the same behavior (and hence performance) as manually written asynchronous code, but instead avoiding the boiler-plate to do the same thing.

Problems and Limitations – Stack vs. Heap Memory

Also, the profile of your garbage collection will be much different. Spring Framework makes a lot of use of synchronized to implement locking, mostly around local data structures. Over the years, before Virtual Threads were available, we have revised synchronized blocks which might potentially interact with third-party resources, removing lock contention in highly concurrent applications. So Spring is in pretty good shape already owing to its large community and extensive feedback from existing concurrent applications. Our team has been experimenting with Virtual Threads since they were called Fibers. Since then and still with the release of Java 19, a limitation was prevalent, leading to Platform Thread pinning, effectively reducing concurrency when using synchronized.

java project loom

This type of program also scales better, which is one reason reactive programming has become very popular in recent times. Vert.x is one such library that helps Java developers write code in a reactive manner. Another reason to avoid virtual threads is with existing code that java project loom depends on the limits or bottlenecks of platform threads to throttle their app’s usage of other resources. For example, if a database server is limited to 10 simultaneous connections, then some app have been written to use an executor service backed by only 8 or 9 threads.

User Threads and Kernel Threads

They are suitable for thread-per-request programming styles without having the limitations of OS threads. You can create millions of virtual threads without affecting throughput. This is quite similar to coroutines, like goroutines, made famous by the Go programming language (Golang). With Project Loom, we will have at least one more such option to choose from. In the preview build of Java, call the new Executors.newVirtualThreadPerTaskExecutor() to get an executor service backed by virtual threads. As the test results show, the test operation took much longer for traditional threads to execute compared to virtual threads.

At a high level, a continuation is a representation in code of the execution flow. In other words, a continuation allows the developer to manipulate the execution flow by calling functions. The Loom docs present the example seen in Listing 3, which provides a good mental picture of how this works. If you were ever exposed to Quasar, which brought lightweight threading to Java via bytecode manipulation, the same tech lead (Ron Pressler) heads up Loom for Oracle. With this new version, the threads look much better (see below). By default, the Fiber uses the ForkJoinPool scheduler, and, although the graphs are shown at a different scale, you can see that the number of JVM threads is much lower here compared to the one thread per task model.

What the Heck Is Project Loom for Java?

When we start such a thread here on line two, this thread will run somewhere in the background. The virtual machine will make sure that our current flow of execution can continue, but this separate thread actually runs somewhere. At this point in time, we have two separate execution paths running at the same time, concurrently. It essentially means that we are waiting for this background task to finish. Typically, we want two things to run concurrently.

Leave a Comment

Your email address will not be published. Required fields are marked *