ScopedValue propagation and API

Michael Stover michael.r.stover at gmail.com
Mon Feb 23 14:18:02 UTC 2026


I've been using Scoped Values heavily for some time for a variety of things and just thought I'd share a couple thoughts . I'm currently using JDK 25.

First, really simply, the ScopedValue.get() method throws a runtime exception if the value is not bound. Ok, kind of like Optional. But, it seems ScopedValue.orElse(null) also throws a runtime exception, which makes it awkward to safely get the currently scoped value or null. Instead we have to do:
if(scopedValue.isBound()) return scopedValue.get();
else return null;

Or use a static NullObject pattern. If we give orElse() a new Object, we're creating that new object every time regardless of whether it's needed. So, calling isBound() all the time seems overly verbose and tedious, and it appears to be a bit of a performance hit from my testing as well, as it's an expensive operation, and I guess we're now doing it twice.
So I think that could be improved so one can get a null out, or at least give us an idiom that isn't a performance drag.
Secondly, the propagation of ScopedValues in StructuredConcurrency is nice, but it's limited to simply copying the reference to the ScopedValue to all the sub-threads. For some purposes, that works fine, but there are surely cases where what we'd want is a child context created, probably from the parent.

If the propagation routine could discover that a ScopedValue would prefer to create a child scoped value rather than just copying the parent scoped value to all sub-threads, then when creating a ScopedValue we could control how it propagates. If the ScopedValue implemented an interface such as "PropagatingScopedValue" or whatever, then it could have the opportunity to create it's child object for each sub-thread. Currently what I do to enable this is create a ThreadFactory to pass to the StructuredTaskScope.open() method, but this is inadequate as it forces the code that creates the sub-threads to know about any and all ScopedValues in play and how they want to propagate. I think that knowledge belongs on the ScopedValue itself and then the jdk code that does the propagation can defer to each ScopedValue for how it wishes to propagate. Maybe some performance implications there, but I leave to the JDK maintainers!

Thank you for all your work!
Michael Stover

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20260223/ea5cf053/attachment.htm>


More information about the loom-dev mailing list