Class ExtentLocal<T>

java.lang.Object
jdk.incubator.concurrent.ExtentLocal<T>
Type Parameters:
T - the extent local's type

public final class ExtentLocal<T> extends Object
Represents a variable that is local to an extent.

An extent-local variable (hereinafter called an extent local) differs from a normal variable in that it is dynamically scoped and intended for cases where context needs to be passed from a caller to a transitive callee without using an explicit parameter. An extent-local variable does not have a default/initial value: it is bound, meaning it gets a value, when executing an operation specified to where(ExtentLocal, Object). Code executed by the operation uses the get() method to get the value of the extent local. The extent local reverts to being unbound (or its previous value) when the operation completes.

Access to the value of an extent local is controlled by the accessibility of the ExtentLocal object. A ExtentLocal object will typically be declared in a private static field so that it can only be accessed by code in that class (or other classes within its nest).

Extent locals support nested bindings. If an extent local has a value then the runWithBinding or callWithBinding can be invoked to run another operation with a new value. Code executed by this methods "sees" the new value of the extent local. The extent local reverts to its previous value when the operation completes.

Unless otherwise specified, passing a null argument to a constructor or method in this class will cause a NullPointerException to be thrown.

API Note:
The following example uses an extent local to make credentials available to callees.

   private static final ExtentLocal<Credentials> CREDENTIALS = ExtentLocal.newInstance();

   Credentials creds = ...
   ExtentLocal.where(CREDENTIALS, creds).run(() -> {
       :
       Connection connection = connectDatabase();
       :
   });

   Connection connectDatabase() {
       Credentials credentials = CREDENTIALS.get();
       :
   }
 
Implementation Note:
Extent locals are designed to be used in fairly small numbers. get() initially performs a linear search through enclosing scopes to find a extent local's innermost binding. It then caches the result of the search in a small thread-local cache. Subsequent invocations of get() for that extent local will almost always be very fast. However, if a program has many extent locals that it uses cyclically, the cache hit rate will be low and performance will be poor. On the other hand, this design allows extent-local inheritance by StructuredTaskScope threads to be very fast: in essence, no more than copying a pointer, and leaving a extent-local binding also requires little more than updating a pointer. Because the extent-local per-thread cache is small, you should try to minimize the number of bound extent locals in use. For example, if you need to pass a number of values as extent locals, it makes sense to create a record class to hold those values, and then bind a single extent local to an instance of that record.
Since:
19
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    An immutable map from a set of ExtentLocals to their bound values.
  • Method Summary

    Modifier and Type
    Method
    Description
    get()
    Returns the value of the extent local.
    final int
    Returns a hash code value for the object.
    boolean
    Returns true if the extent local is bound to a value.
    static <T> ExtentLocal<T>
    Creates an extent-local handle to refer to a value of type T.
    orElse(T other)
    Return the value of the extent local if bound, otherwise returns other.
    <X extends Throwable>
    T
    orElseThrow(Supplier<? extends X> exceptionSupplier)
    Return the value of the extent local if bound, otherwise throw an exception produced by the exception supplying function.
    where(ExtentLocal<T> key, T value)
    Create a binding for an ExtentLocal instance.
    static <T> void
    where(ExtentLocal<T> key, T value, Runnable op)
    Creates a binding for an ExtentLocal instance and runs an operation with that bound ExtentLocal.
    static <T, U> U
    where(ExtentLocal<T> key, T value, Callable<U> op)
    Creates a binding for an ExtentLocal instance and runs a value-returning operation with that bound ExtentLocal.

    Methods declared in class java.lang.Object

    clone, equals, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • hashCode

      public final int hashCode()
      Description copied from class: Object
      Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by HashMap.

      The general contract of hashCode is:

      • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
      • If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
      • It is not required that if two objects are unequal according to the equals method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
      Overrides:
      hashCode in class Object
      Returns:
      a hash code value for this object.
      See Also:
    • where

      public static <T> ExtentLocal.Carrier where(ExtentLocal<T> key, T value)
      Create a binding for an ExtentLocal instance. That ExtentLocal.Carrier may be used later to invoke a Callable or Runnable instance. More bindings may be added to the ExtentLocal.Carrier by the ExtentLocal.Carrier.where(ExtentLocal, Object) method.
      Type Parameters:
      T - the type of the ExtentLocal
      Parameters:
      key - the ExtentLocal to bind
      value - The value to bind it to
      Returns:
      A Carrier instance that contains one binding, that of key and value
    • where

      public static <T, U> U where(ExtentLocal<T> key, T value, Callable<U> op) throws Exception
      Creates a binding for an ExtentLocal instance and runs a value-returning operation with that bound ExtentLocal.
      Type Parameters:
      T - the type of the ExtentLocal
      U - the type of the Result
      Parameters:
      key - the ExtentLocal to bind
      value - The value to bind it to
      op - the operation to call
      Returns:
      the result
      Throws:
      Exception - if the operation completes with an exception
    • where

      public static <T> void where(ExtentLocal<T> key, T value, Runnable op)
      Creates a binding for an ExtentLocal instance and runs an operation with that bound ExtentLocal.
      Type Parameters:
      T - the type of the ExtentLocal
      Parameters:
      key - the ExtentLocal to bind
      value - The value to bind it to
      op - the operation to run
    • newInstance

      public static <T> ExtentLocal<T> newInstance()
      Creates an extent-local handle to refer to a value of type T.
      Type Parameters:
      T - the type of the extent local's value.
      Returns:
      a extent-local handle
    • get

      public T get()
      Returns the value of the extent local.
      Returns:
      the value of the extent local
      Throws:
      NoSuchElementException - if the extent local is not bound (exception is TBD)
    • isBound

      public boolean isBound()
      Returns true if the extent local is bound to a value.
      Returns:
      true if the extent local is bound to a value, otherwise false
    • orElse

      public T orElse(T other)
      Return the value of the extent local if bound, otherwise returns other.
      Parameters:
      other - the value to return if not bound, can be null
      Returns:
      the value of the extent local if bound, otherwise other
    • orElseThrow

      public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
      Return the value of the extent local if bound, otherwise throw an exception produced by the exception supplying function.
      Type Parameters:
      X - Type of the exception to be thrown
      Parameters:
      exceptionSupplier - the supplying function that produces an exception to be thrown
      Returns:
      the value of the extent local if bound
      Throws:
      X - if the extent local is unbound