Skip to content

CONCEPT Cited by 1 source

Virtual thread

A virtual thread (VT) is a JVM-managed lightweight thread that multiplexes onto a small pool of OS-backed worker threads — the carrier threads — via continuations. Introduced in Java 19 as preview and stabilised in Java 21 via JEP 444.

The model

"A virtual thread is not mapped 1:1 to a dedicated OS-level thread. Rather, we can think of it as a task that is scheduled to a fork-join thread pool. When a virtual thread enters a blocking call, like waiting for a Future, it relinquishes the OS thread it occupies and simply remains in memory until it is ready to resume. In the meantime, the OS thread can be reassigned to execute other VTs in the same fork-join pool. This allows us to multiplex a lot of VTs to just a handful of underlying OS threads." (Source: sources/2024-07-29-netflix-java-21-virtual-threads-dude-wheres-my-lock)

A VT is "mounted" on a carrier while executing and "unmounted" while waiting. Mount/unmount is mechanically driven by continuations — the JVM captures the VT's execution state (frame stack, program counter) to the heap on unmount and restores it on mount.

Why it matters

The classical JVM concurrency ceiling is the platform-thread pool size (typically ~200 in Tomcat defaults). With VTs, the ceiling becomes "how many VT tasks can the JVM multiplex over its carrier pool" — which can be millions for low-contention workloads (I/O-bound web handlers that spend most of their time waiting on downstream RPCs).

This is the selling point — VTs let you keep the simple blocking-per-request programming model (patterns/blocking-model-per-request-tomcat) while scaling past the platform-thread-pool cap.

The hazard — pinning

VTs cannot unmount from their carrier in certain JVM states. The most important case: a blocking call inside a synchronized block pins the VT to its carrier for the entire block. See concepts/virtual-thread-pinning.

If enough VTs pin simultaneously, the carrier-thread pool is exhausted; the JVM can still create VTs, but none can mount. New request-VTs queue behind the pinned ones, and the application appears to hang from the outside.

Seen in

Last updated · 319 distilled / 1,201 read