Lesson 11 / 39
Virtual Threads (Java 21)
Handle massive concurrency with lightweight virtual threads that make blocking code cheap, and know when platform threads still fit.
Threads that are cheap
A virtual thread is scheduled by the JVM, not the OS, so you can run millions of them. When one blocks on I/O, the JVM parks it and reuses the carrier thread. This keeps the simple thread-per-request style scalable.
Creating virtual threads
Use Thread.ofVirtual() or an executor that starts one virtual thread per task.
Thread.ofVirtual().name("worker-1").start(() -> fetch(url));
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (String u : urls) {
executor.submit(() -> fetch(u)); // one cheap thread per task
}
} // close() waits for all tasksVirtual threads help I/O-bound work, not CPU-bound loops. Do not pool them, avoid long synchronized blocks around blocking calls, and use ReentrantLock instead.
Quick check
Quick check: What are virtual threads best suited for?
- Many concurrent blocking I/O tasks
- CPU-bound number crunching only
- Replacing the garbage collector
- Compiling code
Answer
Many concurrent blocking I/O tasks — They make blocking I/O cheap so you can scale thread-per-task code.