Phase 19 of 20 · Topic 19.4

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.