Project Loom's virtual threads behave differently from OS-level threads for CPU-bound workloads. Unlike IO-bound code where virtual threads yield on blocking calls, CPU-bound code never triggers an unmount from the carrier thread, resulting in unfair scheduling. A benchmark on an M1 Mac with 64 virtual threads shows they execute in sequential batches of 8 (matching CPU core count) rather than concurrently, unlike OS threads which distribute work fairly. Adding a blocking call like Thread.sleep() restores fair scheduling. Thread.yield() does not currently cause virtual threads to yield. The author notes that Go goroutines gained similar yield support in version 1.14, and suggests Java may follow suit, either via explicit yield support or safepoint-based preemption.

7m read timeFrom morling.dev
Post cover image

Sort: