Virtual thread executor
Code Comparison
ExecutorService exec =
Executors.newFixedThreadPool(10);
try {
futures = tasks.stream()
.map(t -> exec.submit(t))
.toList();
} finally {
exec.shutdown();
}
try (var exec = Executors
.newVirtualThreadPerTaskExecutor()) {
var futures = tasks.stream()
.map(exec::submit)
.toList();
}
Why the modern way wins
♾️
No sizing
No pool size to tune — create as many threads as needed.
⚡
Lightweight
Virtual threads use KB of memory, not MB.
🧹
Auto-closeable
try-with-resources handles shutdown automatically.
Old Approach
Fixed Thread Pool
Modern Approach
Virtual Thread Executor
JDK Support
Virtual thread executor
Available
Widely available since JDK 21 LTS (Sept 2023)
How it works
The virtual thread executor creates a new virtual thread for each task. No pool sizing needed — virtual threads are cheap enough to create millions of them.
Related Documentation
Proof