< prev index next >

src/jdk.incubator.concurrent/share/classes/jdk/incubator/concurrent/StructuredTaskScope.java

Print this page
*** 220,14 ***
   *   <li> A parent-child relation is established with nesting. If a thread opens task
   *   scope "B", then opens task scope "C" (before it closes "B"), then the enclosing task
   *   scope "B" is the parent of the nested task scope "C".
   * </ul>
   *
!  * <p> The tree structure supports confinement checks. The phrase "threads contained in
!  * the task scope" in method descriptions means threads started in the task scope or
!  * descendant scopes. {@code StructuredTaskScope} does not define APIs that exposes the
!  * tree structure at this time.
   *
   * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
   * or method in this class will cause a {@link NullPointerException} to be thrown.
   *
   * <h2>Memory consistency effects</h2>
--- 220,45 ---
   *   <li> A parent-child relation is established with nesting. If a thread opens task
   *   scope "B", then opens task scope "C" (before it closes "B"), then the enclosing task
   *   scope "B" is the parent of the nested task scope "C".
   * </ul>
   *
!  * <p> The tree structure supports:
!  * <ul>
!  *   <li> Inheritance of {@linkplain ExtentLocal extent-local} variables across threads.
!  *   <li> Confinement checks. The phrase "threads contained in the task scope" in method
+  *   descriptions means threads started in the task scope or descendant scopes.
+  * </ul>
+  *
+  * <p> The following example demonstrates the inheritance of an extent-local variable. An
+  * extent local {@code NAME} is bound to the value "duke". A StructuredTaskScope is created
+  * and its {@code fork} method invoked to start a thread to execute {@code childTask}.
+  * The thread inherits the extent-local {@linkplain ExtentLocal.Carrier bindings} captured
+  * when creating the task scope. The code in {@code childTask} uses the value of the
+  * extent-local and so reads the value "duke".
+  * {@snippet lang=java :
+  *     private static final ExtentLocal<String> NAME = ExtentLocal.newInstance();
+  *
+  *     // @link substring="where" target="ExtentLocal#where" :
+  *     ExtentLocal.where(NAME, "duke").run(() -> {
+  *         try (var scope = new StructuredTaskScope<String>()) {
+  *
+  *             scope.fork(() -> childTask());           // @highlight substring="fork"
+  *             ...
+  *          }
+  *     });
+  *
+  *     ...
+  *
+  *     String childTask() {
+  *         String name = NAME.get();   // "duke"    // @highlight substring="get"
+  *         ...
+  *     }
+  * }
+  *
+  * <p> {@code StructuredTaskScope} does not define APIs that exposes the tree structure
+  * at this time.
   *
   * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
   * or method in this class will cause a {@link NullPointerException} to be thrown.
   *
   * <h2>Memory consistency effects</h2>

*** 278,10 ***
--- 309,16 ---
       * scope is optionally named for the purposes of monitoring and management. The thread
       * factory is used to {@link ThreadFactory#newThread(Runnable) create} threads when
       * tasks are {@linkplain #fork(Callable) forked}. The task scope is owned by the
       * current thread.
       *
+      * <p> This method captures the current thread's {@linkplain ExtentLocal extent-local}
+      * bindings for inheritance by threads created in the task scope. The
+      * <a href="#TreeStructure">Tree Structure</a> section in the class description
+      * details how parent-child relations are established implicitly for the purpose of
+      * inheritance of extent-local bindings.
+      *
       * @param name the name of the task scope, can be null
       * @param factory the thread factory
       */
      public StructuredTaskScope(String name, ThreadFactory factory) {
          this.factory = Objects.requireNonNull(factory, "'factory' is null");

*** 365,11 ***
      protected void handleComplete(Future<T> future) { }
  
      /**
       * Starts a new thread to run the given task.
       *
!      * <p> The new thread is created with the task scope's {@link ThreadFactory}.
       *
       * <p> If the task completes before the task scope is {@link #shutdown() shutdown}
       * then the {@link #handleComplete(Future) handle} method is invoked to consume the
       * completed task. The {@code handleComplete} method is run when the task completes
       * with a result or exception. If the {@code Future} {@link Future#cancel(boolean)
--- 402,13 ---
      protected void handleComplete(Future<T> future) { }
  
      /**
       * Starts a new thread to run the given task.
       *
!      * <p> The new thread is created with the task scope's {@link ThreadFactory}. It
+      * inherits the current thread's {@linkplain ExtentLocal extent-local} bindings. The
+      * bindings must match the bindings captured when the task scope was created.
       *
       * <p> If the task completes before the task scope is {@link #shutdown() shutdown}
       * then the {@link #handleComplete(Future) handle} method is invoked to consume the
       * completed task. The {@code handleComplete} method is run when the task completes
       * with a result or exception. If the {@code Future} {@link Future#cancel(boolean)

*** 393,10 ***
--- 432,12 ---
       * @param <U> the result type
       * @return a future
       * @throws IllegalStateException if this task scope is closed
       * @throws WrongThreadException if the current thread is not the owner or a thread
       * contained in the task scope
+      * @throws StructureViolationException if the current extent-local bindings are not
+      * the same as when the task scope was created
       * @throws RejectedExecutionException if the thread factory rejected creating a
       * thread to run the task
       */
      public <U extends T> Future<U> fork(Callable<? extends U> task) {
          Objects.requireNonNull(task, "'task' is null");

*** 626,10 ***
--- 667,15 ---
       * <p> A {@code StructuredTaskScope} is intended to be used in a <em>structured
       * manner</em>. If this method is called to close a task scope before nested task
       * scopes are closed then it closes the underlying construct of each nested task scope
       * (in the reverse order that they were created in), closes this task scope, and then
       * throws {@link StructureViolationException}.
+      *
+      * Similarly, if called to close a task scope that <em>encloses</em> {@linkplain
+      * ExtentLocal.Carrier#run(Runnable) operations} with extent-local bindings then
+      * it also throws {@code StructureViolationException} after closing the task scope.
+      *
       * If a thread terminates without first closing task scopes that it owns then
       * termination will cause the underlying construct of each of its open tasks scopes to
       * be closed. Closing is performed in the reverse order that the task scopes were
       * created in. Thread termination may therefore be delayed when the owner has to wait
       * for threads forked in these task scopes to finish.

*** 822,10 ***
--- 868,16 ---
           * The task scope is optionally named for the purposes of monitoring and management.
           * The thread factory is used to {@link ThreadFactory#newThread(Runnable) create}
           * threads when tasks are {@linkplain #fork(Callable) forked}. The task scope is
           * owned by the current thread.
           *
+          * <p> This method captures the current thread's {@linkplain ExtentLocal extent-local}
+          * bindings for inheritance by threads created in the task scope. The
+          * <a href="StructuredTaskScope.html#TreeStructure">Tree Structure</a> section in
+          * the class description details how parent-child relations are established
+          * implicitly for the purpose of inheritance of extent-local bindings.
+          *
           * @param name the name of the task scope, can be null
           * @param factory the thread factory
           */
          public ShutdownOnSuccess(String name, ThreadFactory factory) {
              super(name, factory);

*** 998,10 ***
--- 1050,16 ---
           * The task scope is optionally named for the purposes of monitoring and management.
           * The thread factory is used to {@link ThreadFactory#newThread(Runnable) create}
           * threads when tasks are {@linkplain #fork(Callable) forked}. The task scope
           * is owned by the current thread.
           *
+          * <p> This method captures the current thread's {@linkplain ExtentLocal extent-local}
+          * bindings for inheritance by threads created in the task scope. The
+          * <a href="StructuredTaskScope.html#TreeStructure">Tree Structure</a> section in
+          * the class description details how parent-child relations are established
+          * implicitly for the purpose of inheritance of extent-local bindings.
+          *
           * @param name the name of the task scope, can be null
           * @param factory the thread factory
           */
          public ShutdownOnFailure(String name, ThreadFactory factory) {
              super(name, factory);
< prev index next >