Skip to content

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 synchronized cannot unmount (largely fixed in 24+; JEP 491 eliminates synchronized pinning). Before 24, prefer ReentrantLock for 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 this CompletableFuture exception go" debugging.
  • Scoped values (JEPs 429 → 446 → 487 → final in 25): immutable per-thread bindings that propagate through structured scopes. Replaces most ThreadLocal uses, 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.

Comments