Class ScopedValueUtil

java.lang.Object
cloud.opencode.base.core.thread.ScopedValueUtil

public final class ScopedValueUtil extends Object
ScopedValue Utility - JDK 25 Scoped Values support (JEP 506) ScopedValue 工具类 - JDK 25 作用域值支持 (JEP 506)

Provides safer and more efficient thread-local value passing mechanism than ThreadLocal.

提供比 ThreadLocal 更安全、更高效的线程局部值传递机制。

JDK 25 Features | JDK 25 特性:

  • Immutability - Values cannot be modified within scope - 不可变性:值在作用域内不可修改
  • Auto cleanup - Automatically released when scope ends - 自动清理:作用域结束时自动释放
  • Safe inheritance - Child threads safely inherit parent values - 继承安全:子线程可安全继承父线程的值
  • Better performance - No manual cleanup, no memory leaks - 性能更优:无需手动清理,避免内存泄漏

Comparison with ThreadLocal | 与 ThreadLocal 对比:

ScopedValue vs ThreadLocal comparison | ScopedValue 与 ThreadLocal 对比
FeatureScopedValueThreadLocal
MutabilityImmutableMutable
CleanupAutomaticManual
InheritanceSafeInheritableThreadLocal needed
Memory Leak RiskNoneHigh if not cleaned

Usage Examples | 使用示例:

// Define ScopedValue (typically static final)
private static final ScopedValue<String> USER_ID = ScopedValue.newInstance();
private static final ScopedValue<String> TRACE_ID = ScopedValue.newInstance();

// Bind values and execute task
ScopedValueUtil.runWhere(USER_ID, "user123", () -> {
    String userId = USER_ID.get();  // Get bound value
    processRequest();
});

// Multiple bindings
ScopedValueUtil.runWhere(USER_ID, "user123", TRACE_ID, "trace-abc", () -> {
    processRequest();
});

Thread Safety | 线程安全: Yes - ScopedValue is inherently thread-safe

Performance | 性能特性:

  • Time complexity: O(1) per get/set - 每次获取/设置 O(1)
  • Space complexity: O(1) per scoped value - 每个作用域值 O(1)
Since:
JDK 25, opencode-base-core V1.0.0
Author:
Leon Soo www.LeonSoo.com
See Also:
  • Method Details

    • newScopedValue

      public static <T> ScopedValue<T> newScopedValue()
      Create a new ScopedValue instance 创建新的 ScopedValue 实例
      Type Parameters:
      T - the type of the scoped value
      Returns:
      a new ScopedValue instance
    • runWhere

      public static <T> void runWhere(ScopedValue<T> scopedValue, T value, Runnable task)
      Bind a value to a ScopedValue and execute a Runnable task 将值绑定到 ScopedValue 并执行 Runnable 任务
      Type Parameters:
      T - the type of the scoped value
      Parameters:
      scopedValue - the ScopedValue to bind
      value - the value to bind
      task - the task to execute
    • callWhere

      public static <T, R, X extends Throwable> R callWhere(ScopedValue<T> scopedValue, T value, ScopedValue.CallableOp<R,X> task) throws X
      Bind a value to a ScopedValue and execute a CallableOp task 将值绑定到 ScopedValue 并执行 CallableOp 任务
      Type Parameters:
      T - the type of the scoped value
      R - the return type of the callable
      X - the exception type that may be thrown
      Parameters:
      scopedValue - the ScopedValue to bind
      value - the value to bind
      task - the callable task to execute
      Returns:
      the result of the callable
      Throws:
      X - if the callable throws an exception
    • runWhere

      public static <T1,T2> void runWhere(ScopedValue<T1> sv1, T1 v1, ScopedValue<T2> sv2, T2 v2, Runnable task)
      Bind two values to two ScopedValues and execute a Runnable task 将两个值绑定到两个 ScopedValue 并执行 Runnable 任务
      Type Parameters:
      T1 - the type of the first scoped value
      T2 - the type of the second scoped value
      Parameters:
      sv1 - the first ScopedValue
      v1 - the first value to bind
      sv2 - the second ScopedValue
      v2 - the second value to bind
      task - the task to execute
    • callWhere

      public static <T1, T2, R, X extends Throwable> R callWhere(ScopedValue<T1> sv1, T1 v1, ScopedValue<T2> sv2, T2 v2, ScopedValue.CallableOp<R,X> task) throws X
      Bind two values to two ScopedValues and execute a CallableOp task 将两个值绑定到两个 ScopedValue 并执行 CallableOp 任务
      Type Parameters:
      T1 - the type of the first scoped value
      T2 - the type of the second scoped value
      R - the return type of the callable
      X - the exception type that may be thrown
      Parameters:
      sv1 - the first ScopedValue
      v1 - the first value to bind
      sv2 - the second ScopedValue
      v2 - the second value to bind
      task - the callable task to execute
      Returns:
      the result of the callable
      Throws:
      X - if the callable throws an exception
    • runWhere

      public static <T1,T2,T3> void runWhere(ScopedValue<T1> sv1, T1 v1, ScopedValue<T2> sv2, T2 v2, ScopedValue<T3> sv3, T3 v3, Runnable task)
      Bind three values to three ScopedValues and execute a Runnable task 将三个值绑定到三个 ScopedValue 并执行 Runnable 任务
      Type Parameters:
      T1 - the type of the first scoped value
      T2 - the type of the second scoped value
      T3 - the type of the third scoped value
      Parameters:
      sv1 - the first ScopedValue
      v1 - the first value to bind
      sv2 - the second ScopedValue
      v2 - the second value to bind
      sv3 - the third ScopedValue
      v3 - the third value to bind
      task - the task to execute
    • isBound

      public static <T> boolean isBound(ScopedValue<T> scopedValue)
      Check if a ScopedValue is bound in the current scope 检查 ScopedValue 是否在当前作用域中已绑定
      Type Parameters:
      T - the type of the scoped value
      Parameters:
      scopedValue - the ScopedValue to check
      Returns:
      true if the ScopedValue is bound, false otherwise
    • getOrDefault

      public static <T> T getOrDefault(ScopedValue<T> scopedValue, T defaultValue)
      Get the value of a ScopedValue, or return a default value if not bound 获取 ScopedValue 的值,如果未绑定则返回默认值

      Note: In JDK 25, the default value cannot be null.

      Type Parameters:
      T - the type of the scoped value
      Parameters:
      scopedValue - the ScopedValue to get
      defaultValue - the default value to return if not bound (cannot be null)
      Returns:
      the bound value, or the default value if not bound
    • get

      public static <T> T get(ScopedValue<T> scopedValue)
      Get the value of a ScopedValue 获取 ScopedValue 的值
      Type Parameters:
      T - the type of the scoped value
      Parameters:
      scopedValue - the ScopedValue to get
      Returns:
      the bound value
      Throws:
      NoSuchElementException - if not bound
    • getIfBound

      public static <T> Optional<T> getIfBound(ScopedValue<T> sv)
      Get value if bound, otherwise empty Optional. 如果已绑定则获取值,否则返回空 Optional。
      Type Parameters:
      T - the type of the scoped value
      Parameters:
      sv - the ScopedValue to query
      Returns:
      an Optional containing the bound value, or empty if not bound
      Since:
      JDK 25, opencode-base-core V1.0.3
    • runWhere

      public static void runWhere(ScopedValue.Carrier carrier, Runnable task)
      Run with multiple scoped value bindings via Carrier. 通过 Carrier 运行多个 ScopedValue 绑定。
      Parameters:
      carrier - the Carrier holding scoped value bindings
      task - the task to execute
      Since:
      JDK 25, opencode-base-core V1.0.3
    • callWhere

      public static <R, X extends Throwable> R callWhere(ScopedValue.Carrier carrier, ScopedValue.CallableOp<R,X> task) throws X
      Call with multiple scoped value bindings via Carrier. 通过 Carrier 调用多个 ScopedValue 绑定。
      Type Parameters:
      R - the return type of the callable
      X - the exception type that may be thrown
      Parameters:
      carrier - the Carrier holding scoped value bindings
      task - the callable task to execute
      Returns:
      the result of the callable
      Throws:
      X - if the callable throws an exception
      Since:
      JDK 25, opencode-base-core V1.0.3
    • where

      public static <T> ScopedValue.Carrier where(ScopedValue<T> scopedValue, T value)
      Create a ScopedValue.Carrier with a single binding 创建带有单个绑定的 ScopedValue.Carrier

      Useful for building complex binding chains.

      Type Parameters:
      T - the type of the scoped value
      Parameters:
      scopedValue - the ScopedValue to bind
      value - the value to bind
      Returns:
      a Carrier with the binding