◐ Shell
clean mode source ↗

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