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()));
  }

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