Concurrency advanced

Scoped values

Share data across call stacks safely without ThreadLocal pitfalls.

✕ Java 8
static final ThreadLocal<User> CURRENT =
    new ThreadLocal<>();
void handle(Request req) {
    CURRENT.set(authenticate(req));
    try { process(); }
    finally { CURRENT.remove(); }
}
✓ Java 25
static final ScopedValue<User> CURRENT =
    ScopedValue.newInstance();
void handle(Request req) {
    ScopedValue.where(CURRENT,
        authenticate(req)
    ).run(this::process);
}
🔒

Immutable

Callees can read but never modify the scoped value.

🧹

Auto cleanup

No manual remove() — value is scoped to the block.

Virtual-thread safe

Works efficiently with millions of virtual threads.

Old Approach
ThreadLocal
Modern Approach
ScopedValue
Since JDK
25
Difficulty
advanced
Scoped values
Available

Finalized in JDK 25 LTS (JEP 506, Sept 2025).

How it works

ScopedValue provides immutable, inheritable, scope-limited context. Unlike ThreadLocal, scoped values are automatically cleaned up, work with virtual threads, and can't be mutated by callees.

Share 𝕏 🦋 in