Scoped Values
Безопасный обмен данными по стеку вызовов без ловушек ThreadLocal.
Сравнение кода
✕ 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);
}
Заметили проблему в этом коде? Сообщите нам.
Почему современный подход лучше
Неизменяемость
Вызываемые методы могут читать Scoped Value, но не могут его изменить.
Автоматическая очистка
Нет ручного remove() — значение ограничено блоком.
Совместимость с виртуальными потоками
Эффективно работает с миллионами виртуальных потоков.
Старый подход
ThreadLocal
Современный подход
ScopedValue
Начиная с JDK
25
Сложность
Продвинутый
Поддержка JDK
Scoped Values
Доступно
Финализировано в JDK 25 LTS (JEP 506, сент. 2025).
Как это работает
ScopedValue предоставляет неизменяемый, наследуемый, ограниченный контекст. В отличие от ThreadLocal, Scoped Values автоматически очищаются, работают с виртуальными потоками и не могут быть изменены вызываемыми методами.
Связанная документация
Доказательство