Week 15 - Virtual Threads, Structured Concurrency, and Scoped Values¶
Conceptual Core¶
Project Loom changes the cost model of concurrency in the JVM. A virtual thread is a JVM-managed continuation scheduled onto a small pool of carrier OS threads. You can have millions cheaply. Blocking I/O is no longer expensive. This obsoletes the primary motivation for reactive programming in most server-side workloads.
Mechanical Detail¶
Thread.ofVirtual().start(runnable),Thread.startVirtualThread,Executors.newVirtualThreadPerTaskExecutor(). Always use the executor in production code.- A virtual thread parks when it hits a JDK-blocking call (
Socket.read,Files.read,LockSupport.park,Thread.sleep). The carrier thread is freed to run another virtual thread. The JVM handles continuation save/restore. - Pinning - the one footgun: a virtual thread inside
synchronizedcannot unmount (largely fixed in 24+; JEP 491 eliminates synchronized pinning). Before 24, preferReentrantLockfor any code path that may block under the lock. - Structured concurrency (JEPs 428 → 453 → 462 → 480 → 505, final in 25):
try (var scope = StructuredTaskScope.open()) { ... }. All forked subtasks are joined or cancelled at scope exit. Eliminates orphan tasks and "where did thisCompletableFutureexception go" debugging. - Scoped values (JEPs 429 → 446 → 487 → final in 25): immutable per-thread bindings that propagate through structured scopes. Replaces most
ThreadLocaluses, cleanly compatible with virtual threads, no leak risk.
Lab¶
Redo week 14's web scraper with Executors.newVirtualThreadPerTaskExecutor() + StructuredTaskScope. Compare lines of code and readability to the three previous versions. Stress to 100k concurrent requests. Watch with JFR's virtual-thread events.
Idiomatic Drill¶
Find every ThreadLocal in a codebase. Classify: replaceable with ScopedValue? required by a legacy API (MDC, security context)? Genuinely needed?
Production Hardening Slice¶
Add JFR events jdk.VirtualThreadPinned and jdk.VirtualThreadSubmitFailed to your monitoring. Any pinning over a few ms is an alert.