Java 21 introduced virtual threads — lightweight, JVM-managed threads.
- import java.util.concurrent.*;
- public class VirtualThreads {
- public static void main(String[] args) throws Exception {
- try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
- for (int i = 0; i < 100_000; i++) {
- final int n = i;
- executor.submit(() -> {
- Thread.sleep(1000);
- return n;
- });
- }
- }
- System.out.println("Done!");
- }
- }
- 100,000 OS threads would crash. 100,000 virtual threads is fine!
- Virtual threads are extremely cheap and heap-allocated — create one per task, no pooling.
- The JVM multiplexes them onto OS threads, unmounting transparently on block. Similar to Go's goroutines.
- Existing blocking code works as-is. Avoid synchronized/JNI — they pin virtual threads to OS threads!
- Similar motivation to Go's goroutines.