import java.time.*;
import java.util.concurrent.*;
import java.util.stream.*;
// *** before: ***
// a task held a thread of the operating system, so threads were counted
// and shared through a pool:
ExecutorService pool = Executors.newFixedThreadPool(200);
pool.submit(() -> System.out.println("task on " + Thread.currentThread()));
pool.shutdown();
// *** in version 21: ***
Thread vt = Thread.ofVirtual().start(() ->
System.out.println("virtual " + Thread.currentThread()));
vt.join();
// one thread per task, and a hundred thousand of them is normal:
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i ->
executor.submit(() -> {
Thread.sleep(Duration.ofMillis(10)); // the carrier is freed
//here
return i;
}));
} // close waits for every task
System.out.println(Thread.currentThread().isVirtual());