Java 21 Virtual Threads and Structured Concurrency
Fast recall
Quick revision
Core answer
Awareness of Project Loom and how it changes the concurrency model for IO-bound Java services — a hot topic for any 2024+ backend role.
Assuming virtual threads make CPU-bound code faster. They don't. Virtual threads only help when threads block on IO — they free the carrier thread to run other virtual threads during the block.
Discuss pinning (synchronized blocks pin the carrier thread), thread-local variable caveats, and the StructuredTaskScope API for fan-out patterns with automatic cancellation.
Interview-ready guide
Interview answer
Virtual threads make thread-per-request viable by making threads cheap — ~1KB initial stack, JVM-scheduled onto a small pool of carrier threads.
How they work:
- When a virtual thread calls blocking I/O, it unmounts from the carrier — the carrier is freed for other virtual threads
- Millions can run concurrently; JVM manages scheduling; carrier pool defaults to N = number of CPU cores
Carrier pinning (main migration concern):
synchronizedblock pins the virtual thread to its carrier — cannot unmount during the block- If the block contains I/O, that carrier thread is wasted — effectively a blocking platform thread again
- Fix: replace
synchronizedwithReentrantLockon I/O-heavy paths
Migration guidelines:
- Do not pool virtual threads — pooling defeats the purpose; use
Executors.newVirtualThreadPerTaskExecutor() ThreadLocalworks but risks memory waste with millions of threads — ScopedValue is the replacement- Enable
-Djdk.tracePinnedThreads=shortduring testing to findsynchronizedblocks that need migration
I recommend virtual threads for I/O-heavy workloads like HTTP servers and database-heavy services. CPU-bound computation still benefits from platform threads with ForkJoinPool.
Java 21 Virtual Threads and Structured Concurrency
Direct Answer
Virtual threads are lightweight JVM-managed threads that mount on a small pool of OS (carrier) threads. When a virtual thread blocks on IO, it unmounts, freeing the carrier for another virtual thread. This enables a thread-per-request model at scale without the memory cost of millions of platform threads.
Deep Dive & Architecture
Virtual threads (JEP 444, Java 21 GA) are lightweight, JVM-managed threads that let you write simple one-thread-per-request blocking code while scaling to millions of concurrent threads.
They look and feel identical to java.lang.Thread (they are subclasses) but are scheduled by the JVM onto a small pool of carrier threads (by default, ForkJoinPool sized to CPUs).
When a virtual thread hits a blocking I/O call (socket read, HTTP, JDBC), the JVM unmounts it from the carrier — stack gets parked on the heap, carrier goes to serve another virtual thread. The memory cost is kilobytes, not megabytes — a platform thread's 1 MB default stack becomes a resizable heap object. Create them with Thread.ofVirtual().start(task) or Executors.newVirtualThreadPerTaskExecutor(). The goal: kill thread pools for I/O-bound server code and let you write straight-line blocking logic without callback hell or reactive complexity.
Pinning is when a virtual thread cannot be unmounted from its carrier — usually because it's inside a synchronized block or executing a native (JNI) frame. While pinned, any blocking I/O holds the carrier thread, defeating the whole point of Loom. If many virtual threads pin simultaneously on blocking I/O, carriers get exhausted: no virtual thread can run because there's no free carrier.
Common Mistakes & Pitfalls
Assuming virtual threads make CPU-bound code faster. They don't. Virtual threads only help when threads block on IO — they free the carrier thread to run other virtual threads during the block.
Check your understanding
Answer these without looking back at the article.
- What are virtual threads in Java 21 (Project Loom)? How do they differ from platform threads?
- When should you use virtual threads vs platform threads? What are the best and worst workloads?
- What is virtual thread pinning in Java 21 and how do you avoid it?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.