Java 21 - Virtual Threads (Project Loom)

 

What are Virtual Threads?

 

Virtual threads in Java 21 are lightweight, non-native threads that allow high concurrency by suspending when blocked, making them ideal for tasks with frequent I/O operations.

In contrast to platform threads, the virtual threads are not wrappers of OS threads.
They are lightweight Java entities (with their own stack memory with a small footprint – only a few hundred bytes) that are cheap to create, block, and destroy. 
We can create many of them at the same time (millions) so they sustain a massive throughput.

 

Java 11:

 

In Java 11, traditional threads (platform threads) are used. These threads are mapped 1:1 to kernel threads scheduled by the operating system.

Platform threads are relatively heavy, consuming between 2 and 10 MB of memory by default.
The 1:1 mapping of platform threads creates a bottleneck, limiting the number of threads that can be utilized without drawbacks.
Asynchronous programming is often used to mitigate this limitation, but it introduces complexity and can be harder to debug.

 

Java 21:

 

Virtual threads are JVM-managed lightweight threads introduced in Java 21.
They are designed for high-throughput concurrent applications.

Key benefits:

  • Lightweight: Virtual threads are much lighter than platform threads.

  • Scalability: Millions of virtual threads can be executed using only a few operating system threads.

  • No code modification: Existing Java code can utilize virtual threads without changes.

  • Unlike platform threads, virtual threads are not directly tied to native threads.

Creating a virtual thread

Runnable runnable = () -> System.out.println("Inside Runnable");
Thread.startVirtualThread(runnable); // Using Thread API
Thread virtualThread = Thread.ofVirtual().start(runnable); // Using Executors

As you can see virtual threads using the same Objects like "Runnable" as you would use in older Java Versions.

Additional example with a "Callable" and executors

ThreadFactory factory = Thread.ofVirtual().factory();
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(0, factory);

Callable<String> scheduledCallable = () -> {
       System.out.println("Done");
       return "Done 2";
};

var out = scheduledExecutorService.schedule(scheduledCallable, 1, TimeUnit.SECONDS);
System.out.println(out.get());

When code running in a virtual thread calls a blocking I/O operation, the Java runtime suspends the virtual thread until it can be resumed

The JVM do the Heavy lifting and managing of these virtual threads.

 

Remember that virtual threads are not inherently faster than platform threads.
They are best suited for tasks that spend most of their time waiting, such as server applications handling client requests with blocking I/O operations.
For resource-intensive tasks, continue using traditional platform threads.

 

Why Use Virtual Threads (and why not to use it)?

 

  • Scalability: Virtual threads allow you to create a large number of lightweight threads without consuming excessive memory. They efficiently manage concurrency.

  • Responsiveness: By suspending when blocked (e.g., during I/O operations), virtual threads avoid thread contention and context switching overhead.

  • Ease of Use: Existing Java code can utilize virtual threads without modification, making adoption straightforward.

scenarios where using virtual threads might not be the best choice:

  • CPU-Intensive Tasks: Virtual threads are not suitable for long-running CPU-intensive operations.

  • For compute-bound tasks (where the rate of progress is primarily limited by the speed of the CPU),
    traditional platform threads (native threads) are still more appropriate.

 

Before jumping in and use virtual threads everywhere, consider the implications and possible pitfalls.
Like

  • are thread local variables possible and handled?

  • are thread pools involved and what effect does it have?

  • does the libraries used, understand and support virtual threads?

  • .... 

As always think and understand the tools before using them. 🤔

While virtual threads are powerful, they are not a silver bullet.

 

Have fun with threads in Java 21 😊