Class ScopedLocal<T>

java.lang.Object
org.apache.groovy.runtime.async.ScopedLocal<T>
Type Parameters:
T - the type of the scoped value

public abstract class ScopedLocal<T> extends Object
A thread-scoped value holder that abstracts over ThreadLocal (JDK < 25) and java.lang.ScopedValue (JDK 25+), presenting a unified API modelled after ScopedValue.

Backend selection

On JDK 25+, where finalized java.lang.ScopedValue is available, this class delegates to the ScopedValue API. On earlier JDK versions it falls back to a conventional ThreadLocal with save-and-restore semantics.

API overview

The API mirrors the main ScopedValue operations:

Usage


 private static final ScopedLocal<String> REQUEST_ID =
         ScopedLocal.newInstance();

 ScopedLocal.where(REQUEST_ID, "req-42").run(() -> {
     assert "req-42".equals(REQUEST_ID.get());
 });

 ScopedLocal.where(REQUEST_ID, "req-1")
         .where(TENANT_ID, "acme")
         .call(() -> handleRequest());

 String result = REQUEST_ID.where("req-7", () -> process());

 private static final ScopedLocal<MyCtx> CTX =
         ScopedLocal.withInitial(MyCtx::new);
 
Since:
6.0.0
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    An immutable set of scoped-local bindings that can be applied atomically for the duration of a Runnable or Supplier.
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    abstract T
    get()
    Returns the value bound to this scoped-local on the current thread.
    abstract boolean
    Returns true if an explicit binding is active or an initial supplier is configured.
    static <T> ScopedLocal<T>
    Creates a new ScopedLocal with no initial value.
    abstract T
    orElse(T other)
    Returns the value bound to this scoped-local, or other if no binding is active and no initial supplier is configured.
    abstract <X extends Throwable>
    T
    orElseThrow(Supplier<? extends X> exceptionSupplier)
    Returns the value bound to this scoped-local if available, otherwise throws an exception produced by the exceptionSupplier.
    where(ScopedLocal<T> key, T value)
    Creates a ScopedLocal.Carrier that binds key to value.
    final void
    where(T value, Runnable action)
    Binds this scoped-local to value for the duration of the action, then restores the previous binding.
    final <R> R
    where(T value, Supplier<R> supplier)
    Binds this scoped-local to value for the duration of the supplier, then restores the previous binding.
    static <T> ScopedLocal<T>
    withInitial(Supplier<? extends T> initialSupplier)
    Creates a new ScopedLocal whose get() method returns a lazily initialized default when no explicit binding exists.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • ScopedLocal

      public ScopedLocal()
  • Method Details

    • newInstance

      public static <T> ScopedLocal<T> newInstance()
      Creates a new ScopedLocal with no initial value.
      Type Parameters:
      T - the value type
      Returns:
      a new unbound scoped-local instance
    • withInitial

      public static <T> ScopedLocal<T> withInitial(Supplier<? extends T> initialSupplier)
      Creates a new ScopedLocal whose get() method returns a lazily initialized default when no explicit binding exists. The supplier is invoked at most once per thread and the result is cached, analogous to ThreadLocal.withInitial(Supplier).
      Type Parameters:
      T - the value type
      Parameters:
      initialSupplier - supplies the default value
      Returns:
      a new scoped-local instance with a default supplier
    • where

      public static <T> ScopedLocal.Carrier where(ScopedLocal<T> key, T value)
      Creates a ScopedLocal.Carrier that binds key to value. The binding takes effect when ScopedLocal.Carrier.run(Runnable) or ScopedLocal.Carrier.call(Supplier) is invoked.
      Type Parameters:
      T - the value type
      Parameters:
      key - the scoped-local to bind
      value - the value to bind; may be null
      Returns:
      a carrier holding the binding
    • get

      public abstract T get()
      Returns the value bound to this scoped-local on the current thread.
      Returns:
      the current value
      Throws:
      NoSuchElementException - if no value is bound and no initial supplier was provided
    • orElse

      public abstract T orElse(T other)
      Returns the value bound to this scoped-local, or other if no binding is active and no initial supplier is configured.
      Parameters:
      other - the fallback value
      Returns:
      the current value or other
    • orElseThrow

      public abstract <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
      Returns the value bound to this scoped-local if available, otherwise throws an exception produced by the exceptionSupplier.

      If an initial supplier is configured (via withInitial(Supplier)), this method returns the initial value rather than throwing.

      Type Parameters:
      X - the type of the exception to throw if not bound
      Parameters:
      exceptionSupplier - a supplier that produces the exception to throw; must not be null
      Returns:
      the current value
      Throws:
      X - if no value is bound and no initial supplier is configured
      NullPointerException - if exceptionSupplier is null
    • isBound

      public abstract boolean isBound()
      Returns true if an explicit binding is active or an initial supplier is configured.
      Returns:
      whether a value is available via get()
    • where

      public final <R> R where(T value, Supplier<R> supplier)
      Binds this scoped-local to value for the duration of the supplier, then restores the previous binding.
      Type Parameters:
      R - the result type
      Parameters:
      value - the value to bind; may be null
      supplier - the action to execute with the binding active
      Returns:
      the supplier's result
    • where

      public final void where(T value, Runnable action)
      Binds this scoped-local to value for the duration of the action, then restores the previous binding.
      Parameters:
      value - the value to bind; may be null
      action - the action to execute with the binding active