Java ScopedValue

Не так давно в процессе миграции старого приложения с 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()));
      }
    

    и уже использовал бы его по мере надобности, когда хочется что то положить что может быть будет вызвано.