CONCEPT Cited by 1 source
Carrier thread¶
A carrier thread is the OS-backed worker thread in the JVM's virtual-thread fork-join pool on which a virtual thread mounts to execute. The term is defined in JEP 444.
"In JVM terminology, the underlying OS thread is referred to as the 'carrier thread' to which a virtual thread can be 'mounted' while it executes and 'unmounted' while it waits." (Source: sources/2024-07-29-netflix-java-21-virtual-threads-dude-wheres-my-lock)
Pool sizing¶
The default fork-join pool size is
Runtime.getRuntime().availableProcessors()
— equal to the vCPU count the JVM sees.
This default is the architectural number that makes pinning dangerous: on a 4-vCPU instance, the pool has only 4 carrier threads. Four simultaneously pinned VTs ⇒ 100% carrier exhaustion ⇒ fleet hang.
Mount / unmount¶
- Mount: the VT task is selected by the scheduler; its continuation is restored; it runs on the carrier.
- Unmount: the VT blocks on a VT-aware primitive (blocking
I/O,
LockSupport.park,ReentrantLock.lock,Future.get); its continuation is saved to the heap; the carrier is released back to the pool. - Pinned: the VT blocks on a non-VT-aware primitive
(inside
synchronized, or in a native frame holding a monitor); the carrier is not released. See concepts/virtual-thread-pinning.
Why this matters for capacity¶
With classical platform threads, an instance's concurrency ceiling is the configured thread-pool size (often hundreds). With VTs, the ceiling is "VT multiplexing factor × carrier pool size" — potentially millions of in-flight VTs on a 4-carrier pool, because each VT is cheap when unmounted.
But the carrier pool is the ultimate bottleneck: whatever is currently holding a carrier is the only thing making forward progress. The scheduler can enqueue VTs indefinitely, but executing them still requires carriers. Pinning is the failure mode where carriers are held without corresponding forward progress.
Seen in¶
- sources/2024-07-29-netflix-java-21-virtual-threads-dude-wheres-my-lock
— Canonical wiki instance. Netflix's 4-vCPU Spring Boot
microservice instances have 4-carrier-thread pools; 4 VTs
pinned in
synchronizedexhausted them; Tomcat's request-handling became inert.
Related¶
- systems/java-21-virtual-threads — Where carrier threads are implemented.
- concepts/virtual-thread — The VT that mounts.
- concepts/virtual-thread-pinning — The failure mode that consumes carriers without making progress.
- concepts/fork-join-pool — The pool carriers live in.
- companies/netflix — Canonical adopter.