Virtual Threads (Java 21+ Project Loom)
1Concept
Virtual Threads (JEP 444) are lightweight user-mode threads managed by the JVM runtime rather than the OS kernel. A single JVM can run millions of virtual threads concurrently. When a virtual thread executes blocking I/O (network/file), the JVM unmounts it from the underlying carrier OS thread, eliminating thread starvation.
2Architecture Diagram
Million Virtual Threads: [ VT 1 ] [ VT 2 ] ... [ VT 1,000,000 ]
|
Mounted onto
v
Small Carrier OS Pool: [ Carrier OS Thread 0 ] [ Carrier OS Thread 1 ]3Code Example
Core Java
public class VirtualThreadsDemo {
public static void main(String[] args) throws Exception {
// Spawning a lightweight Virtual Thread
Thread vThread = Thread.ofVirtual().name("Loom-Worker-01").start(() -> {
System.out.println("Virtual thread running: " + Thread.currentThread());
System.out.println("Is Virtual Thread: " + Thread.currentThread().isVirtual());
});
vThread.join();
System.out.println("Virtual thread completed without exhausting OS thread handles.");
}
}4Expected Output
Virtual thread running: VirtualThread[#21,Loom-Worker-01]/runnable@ForkJoinPool-1-worker-1 Is Virtual Thread: true Virtual thread completed without exhausting OS thread handles.
5Key Takeaways
- ✓Do NOT pool virtual threads; spawn a new virtual thread per task (`Executors.newVirtualThreadPerTaskExecutor()`).
- ✓Avoid `synchronized` blocks inside virtual threads if they execute long I/O (pins the carrier OS thread); use `ReentrantLock` instead.
- ✓Enables simple, synchronous thread-per-request programming models with reactive-scale throughput.