Не так давно в процессе миграции старого приложения с Java8 встретилась лобопытная задачка по миграции ThreadLocal в ScopedValue. ScopeValue уже поддерживает VirtualThreads представленные в JDK21 и в целом более безопасна в использовании.
- Immutable
- Thread safe
- Structured scope
Это все очень здорово, но на мой взгляд не очень удобно в реальной жизни. Все же хочется проверять связаны ли мы с текущим потоком или нет и, что самое главное, далеко не всегдя мы кладем в ThreadLocal/ScopeValue просто один раз взятую откуда то константу и потом ее уже не трогаем - immutable ага.
Чаще все же приходится куда то ходить или расчитывать это значение и только потом складывать в контейнер и может быть его оттуда доставать в случае если уже было добавлено для текущего потока.
Я бы добавил в ScopeValue вот такой сервисный метод:
<F, R> R withEvaluated(ScopedValue<F> scoped,
Supplier<? extends F> factory,
Function<? super F, ? extends R> action) {
if (scoped.isBound()) {
return action.apply(scoped.get());
}
return ScopedValue.where(scoped, factory.get())
.call(() -> action.apply(scoped.get()));
}
и уже использовал бы его по мере надобности, когда хочется что то положить что может быть будет вызвано.