Java 21 Virtual Threads: Lightweight User-Space Concurrency (Project Loom)

Finalized in Java 21 LTS (Project Loom), Virtual Threads represent the most profound evolution in Java concurrency since the language's inception. They allow high-throughput web servers and microservices to run millions of concurrent connections using simple, synchronous code without complex reactive programming.

Java 21 Virtual Threads Architecture Diagram

Figure 12: Architectural Mapping: Millions of lightweight Virtual Threads scheduled onto a small pool of OS Carrier Threads.

Creating Virtual Threads in Java 21+

import java.util.concurrent.Executors;
import java.time.Duration;

public class VirtualThreadDemo {
    public static void main(String[] args) throws Exception {
        // 1. Spawning a single virtual thread
        Thread vThread = Thread.ofVirtual().name("VThread-1").start(() -> {
            System.out.println("Running inside: " + Thread.currentThread());
        });
        vThread.join();

        // 2. Launching 100,000 Concurrent Virtual Threads with Ease!
        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 1; i <= 100_000; i++) {
                final int taskId = i;
                executor.submit(() -> {
                    Thread.sleep(Duration.ofMillis(500)); // Non-blocking sleep!
                    return taskId;
                });
            }
        } // Automatically awaits completion of all 100,000 tasks!
        System.out.println("Successfully executed 100,000 virtual threads without crashing RAM!");
    }
}

Next Step

Congratulations on completing Concurrency! Let us now enter Section 7: File I/O, NIO.2 & JVM Internals. Proceed to: Java File I/O Streams →

Frequently Asked Questions (FAQ)

Q1. What is a Virtual Thread in Java 21?
A Virtual Thread is a lightweight, user-mode thread managed directly by the Java Virtual Machine rather than the underlying Operating System kernel. They are cheap to create (consuming a few hundred bytes vs 1 MB for OS threads), allowing servers to run millions of concurrent threads simultaneously.
Q2. What happens when a Virtual Thread executes a blocking I/O operation?
When a virtual thread blocks (e.g. waiting for a database query or HTTP response), the JVM automatically unmounts it from its OS carrier thread and saves its stack state in the Heap. The carrier thread immediately executes other work. Once the I/O finishes, the JVM mounts the virtual thread back onto an available carrier.
Q3. Do I need thread pools for Virtual Threads?
No! Never pool virtual threads! Virtual threads are so cheap that best practice is to create a fresh virtual thread for every single task or incoming HTTP request (using Executors.newVirtualThreadPerTaskExecutor()).

Explore Related Java Tutorials

Accelerate your Java mastery by studying these tightly connected core tutorials:

ExecutorService →

Virtual thread executors.

Multithreading Basics →

Platform threads comparison.

JVM Architecture →

JVM execution engine.

Java File I/O →

Entering Section 7: File I/O.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!