CONCURRENCY LAB · SCHEDULE · INSPECT · COMPARE

Virtual threads: release a carrier while waiting

Compare retained platform workers with unmounted virtual tasks using the same CPU and I/O workload.

Explicit teaching schedule · no actual worker threads

Exact schedule state

Inspect identities, counters and transitions

Compare scheduling, not fixed stack-size folklore

Every task performs a CPU phase, waits for I/O, then performs an equally sized second CPU phase. The two panels receive identical tasks and the same number of execution slots. In the platform-worker panel, a blocked task retains its worker until I/O completes. In the virtual-task panel, an unmountable wait releases its carrier so another ready task can run. Task states distinguish ready, running, waiting for I/O and done. This replaces a fixed memory multiplier with an explicit schedule that can be inspected tick by tick.

Control the workload and the carrier constraint

Tasks sets the number of jobs; Workers / carriers sets the maximum simultaneously running CPU phases. CPU ticks before and after I/O changes both compute phases. I/O wait duration controls the non-computing interval. Virtual blocking call retains its carrier disables unmounting in the virtual panel for this fixture, illustrating a blocking operation that cannot release the underlying execution resource. It is not labeled as all synchronized code: modern Java changed monitor-related pinning behavior. This offline schedule does not detect or reproduce a particular JDK implementation. Changing any parameter rebuilds both panels from the same initial tasks.

Find the benefit and its boundary

Use twelve tasks, two carriers, two CPU ticks and ten I/O-wait ticks. The unmounted panel can start other tasks while earlier ones wait, so it finishes sooner than the retained-worker panel. Enable carrier retention: the schedules should have the same completion time under these simplified rules. Set I/O wait to zero and compare again. Virtual scheduling does not create additional CPU capacity; both panels must execute the same amount of compute on two slots. Increase carriers and inspect the change in concurrent running tasks. One carrier can still multiplex waits, but it cannot execute two CPU phases in the same modeled tick.

Inspect the resource accounting

Play maps the longer schedule to sixty inspection seconds, keeping both panels on the same modeled tick. A panel that finishes earlier remains complete while the other continues. Pause freezes both; Next state advances one modeled tick; Restart rewinds; Speed changes inspection pace; Inspect time scrubs; Restore defaults resets the inputs. The inspector records each task’s carrier assignment, phase and wake tick. Carrier slots are never assigned to two tasks at once. This non-preemptive, equal-work fixture omits scheduler overhead, I/O capacity limits, cancellation, native calls, memory allocation and platform-thread creation. It makes no fixed stack-size, latency or throughput guarantee. Virtual threads still need workload-specific measurement; the experiment isolates one scheduling mechanism rather than predicting production performance.

Views are my own and do not represent any employer, past or present.

Search