JDK 24's JEP 491 eliminates monitor-related carrier pinning, which previously posed risks for synchronized blocking code when deploying Java 21 virtual threads. While some residual pinning remains for native frames, class loading, and local file I/O on Linux, this update significantly improves virtual thread stability. The JDK Flight Recorder (JFR) jdk.VirtualThreadPinned event continues to be a crucial part of the rollout checklist for identifying these remaining pinning instances.
With the reduction of carrier-thread pinning, the main production risk for virtual thread deployments has moved from carrier-thread starvation to downstream-resource exhaustion. As virtual threads remove the servlet-thread ceiling, concurrency is now limited by factors such as connection pools, rate limits, file descriptors, and the capacity of downstream services. This requires developers to re-evaluate how these resources are managed in high-concurrency environments.
Under virtual threads, ThreadLocal caching silently ceases to function as expected. Benchmarks showed a ThreadLocal.withInitial() cache being initialized 2,216 times more frequently under virtual threads compared to platform threads for the same workload. This unexpected behavior initially manifests as unexplained garbage collection pressure, indicating that ThreadLocal is not suitable for caching in virtual thread environments due to its assumption of thread reuse.
Scoped Values, finalized in JDK 25 via JEP 506, are presented as the appropriate replacement for application-owned request context. They address the propagation issues associated with InheritableThreadLocal and automatically propagate into StructuredTaskScope child tasks. A notable API change during finalization is that ScopedValue.orElse(null) is no longer permitted.
Virtual threads simplify blocking request-response services but do not replace the need for reactive backpressure mechanisms. The combination of Spring MVC with virtual threads is recommended as a strong default for services involving blocking I/O. For streaming, Server-Sent Events (SSE), WebSockets, and systems sensitive to backpressure, Spring WebFlux remains the preferred choice.
✨ This summary was generated by AI from the outlets' reporting listed below. It is not independently verified and may contain errors — check the original sources. How BrevFeed works →
One email each morning: the day's tech stories, clustered across outlets and summarized. No account needed.
One email a day. Unsubscribe in one click, any time.
Spend a few minutes, get the whole day. Every topic's top stories in one hands-free rundown — listen, watch, or read the transcript.
▶ Play today's briefNew every morning, and the back catalogue is archived by date.
JDK 24's JEP 491 removes monitor-related carrier pinning for Java virtual threads, reducing risks for synchronized blocking code. This change shifts the primary production risk from carrier-thread starvation to downstream resource exhaustion, and highlights issues with ThreadLocal caching under virtual threads. Scoped Values, finalized in JDK 25, are introduced as a replacement for application-owned request context.