Не так давно в процессе миграции старого приложения с Java8 встретилась лобопытная задачка
по миграции ThreadLocal в ScopedValue.
ScopeValue уже поддерживает VirtualThreads представленные в JDK21 и в целом более безопасна
в использовании.
Это все очень здорово, но на мой взгляд не очень удобно в реальной жизни.
Все же хочется проверять связаны ли мы с текущим потоком или нет и, что
самое главное, далеко не всегдя мы кладем в 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()));
}
и уже использовал бы его по мере надобности, когда хочется что то положить что может быть будет вызвано.