Card 05/ 08
Platform Threads vs Virtual Threads
One thread per connection used to be impossible at ten thousand connections; with virtual threads it is ordinary.
A platform thread is a Java thread backed by its own operating-system thread. A virtual thread, finalised in Java 21, is scheduled by the Java virtual machine itself, on a small pool of platform threads called carriers. The table compares their cost and scheduling, and the rule after it says when to use each.
A server holding ten thousand open connections could not use one platform thread per connection for twenty years, because each thread reserved around a megabyte of stack and needed a slot in the operating system's scheduler.
| Compared on | Platform thread | Virtual thread |
|---|---|---|
| Backed by | One operating-system thread | A heap object, run on a carrier thread (a platform thread that virtual threads take turns on) |
| Stack | Reserved up front, around a megabyte | Grows and shrinks on the heap |
| Scheduled by | The operating system | The virtual machine |
| Practical number | Thousands | Millions |
| While blocked on input or output | Its operating-system thread is idle | It releases its carrier for someone else |
Starting one virtual thread, and one per task through an executor:
Thread.ofVirtual().start(() -> handle(connection));
try (var pool = Executors.newVirtualThreadPerTaskExecutor()) {
connections.forEach(c -> pool.submit(() -> handle(c)));
}The decision rule. Use virtual threads for work that spends its time waiting: network calls, database queries, file reads. Use platform threads for work that spends its time computing, where there is nothing to release the carrier for, and a pool sized to the number of processors is the right shape.
← → move through sections and cards