< prev index next >

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

Print this page

  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.time.Duration;
  32 import java.time.Instant;
  33 import java.util.Comparator;
  34 import java.util.Objects;
  35 import java.util.Optional;
  36 import java.util.Set;
  37 import java.util.concurrent.Callable;
  38 import java.util.concurrent.CancellationException;
  39 import java.util.concurrent.ConcurrentHashMap;
  40 import java.util.concurrent.ExecutionException;
  41 import java.util.concurrent.Future;
  42 import java.util.concurrent.FutureTask;
  43 import java.util.concurrent.RejectedExecutionException;
  44 import java.util.concurrent.ThreadFactory;
  45 import java.util.concurrent.TimeoutException;
  46 import java.util.concurrent.TimeUnit;
  47 import java.util.concurrent.locks.ReentrantLock;
  48 import java.util.function.Function;
  49 import jdk.internal.misc.PreviewFeatures;
  50 import jdk.internal.misc.ThreadFlock;
  51 
  52 /**
  53  * A basic API for <em>structured concurrency</em>. {@code StructuredTaskScope} supports
  54  * cases where a task splits into several concurrent subtasks, to be executed in their
  55  * own threads, and where the subtasks must complete before the main task continues. A
  56  * {@code StructuredTaskScope} can be used to ensure that the lifetime of a concurrent
  57  * operation is confined by a <em>syntax block</em>, just like that of a sequential
  58  * operation in structured programming.
  59  *
  60  * <h2>Basic usage</h2>
  61  *
  62  * A {@code StructuredTaskScope} is created with one of its public constructors. It defines
  63  * the {@link #fork(Callable) fork} method to start a thread to execute a task, the {@link
  64  * #join() join} method to wait for all threads to finish, and the {@link #close() close}
  65  * method to close the task scope. The API is intended to be used with the {@code
  66  * try-with-resources} construct. The intention is that code in the <em>block</em> uses
  67  * the {@code fork} method to fork threads to execute the subtasks, wait for the threads
  68  * to finish with the {@code join} method, and then <em>process the results</em>.
  69  * Processing of results may include handling or re-throwing of exceptions.

 318      * <p> This method captures the current thread's {@linkplain ScopedValue scoped value}
 319      * bindings for inheritance by threads created in the task scope. The
 320      * <a href="#TreeStructure">Tree Structure</a> section in the class description
 321      * details how parent-child relations are established implicitly for the purpose of
 322      * inheritance of scoped value bindings.
 323      *
 324      * @param name the name of the task scope, can be null
 325      * @param factory the thread factory
 326      */
 327     public StructuredTaskScope(String name, ThreadFactory factory) {
 328         this.factory = Objects.requireNonNull(factory, "'factory' is null");
 329         this.flock = ThreadFlock.open(name);
 330     }
 331 
 332     /**
 333      * Creates an unnamed structured task scope that creates virtual threads. The task
 334      * scope is owned by the current thread.
 335      *
 336      * <p> This constructor is equivalent to invoking the 2-arg constructor with a name
 337      * of {@code null} and a thread factory that creates virtual threads.
 338      *
 339      * @throws UnsupportedOperationException if preview features are not enabled
 340      */
 341     public StructuredTaskScope() {
 342         PreviewFeatures.ensureEnabled();
 343         this.factory = Thread.ofVirtual().factory();
 344         this.flock = ThreadFlock.open(null);
 345     }
 346 
 347     /**
 348      * Throws WrongThreadException if the current thread is not the owner.
 349      */
 350     private void ensureOwner() {
 351         if (Thread.currentThread() != flock.owner())
 352             throw new WrongThreadException("Current thread not owner");
 353     }
 354 
 355     /**
 356      * Throws WrongThreadException if the current thread is not the owner
 357      * or a thread contained in the tree.
 358      */
 359     private void ensureOwnerOrContainsThread() {
 360         Thread currentThread = Thread.currentThread();
 361         if (currentThread != flock.owner() && !flock.containsThread(currentThread))
 362             throw new WrongThreadException("Current thread not owner or thread in the tree");

  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.time.Duration;
  32 import java.time.Instant;
  33 import java.util.Comparator;
  34 import java.util.Objects;
  35 import java.util.Optional;
  36 import java.util.Set;
  37 import java.util.concurrent.Callable;
  38 import java.util.concurrent.CancellationException;
  39 import java.util.concurrent.ConcurrentHashMap;
  40 import java.util.concurrent.ExecutionException;
  41 import java.util.concurrent.Future;
  42 import java.util.concurrent.FutureTask;
  43 import java.util.concurrent.RejectedExecutionException;
  44 import java.util.concurrent.ThreadFactory;
  45 import java.util.concurrent.TimeoutException;
  46 import java.util.concurrent.TimeUnit;
  47 import java.util.concurrent.locks.ReentrantLock;
  48 import java.util.function.Function;

  49 import jdk.internal.misc.ThreadFlock;
  50 
  51 /**
  52  * A basic API for <em>structured concurrency</em>. {@code StructuredTaskScope} supports
  53  * cases where a task splits into several concurrent subtasks, to be executed in their
  54  * own threads, and where the subtasks must complete before the main task continues. A
  55  * {@code StructuredTaskScope} can be used to ensure that the lifetime of a concurrent
  56  * operation is confined by a <em>syntax block</em>, just like that of a sequential
  57  * operation in structured programming.
  58  *
  59  * <h2>Basic usage</h2>
  60  *
  61  * A {@code StructuredTaskScope} is created with one of its public constructors. It defines
  62  * the {@link #fork(Callable) fork} method to start a thread to execute a task, the {@link
  63  * #join() join} method to wait for all threads to finish, and the {@link #close() close}
  64  * method to close the task scope. The API is intended to be used with the {@code
  65  * try-with-resources} construct. The intention is that code in the <em>block</em> uses
  66  * the {@code fork} method to fork threads to execute the subtasks, wait for the threads
  67  * to finish with the {@code join} method, and then <em>process the results</em>.
  68  * Processing of results may include handling or re-throwing of exceptions.

 317      * <p> This method captures the current thread's {@linkplain ScopedValue scoped value}
 318      * bindings for inheritance by threads created in the task scope. The
 319      * <a href="#TreeStructure">Tree Structure</a> section in the class description
 320      * details how parent-child relations are established implicitly for the purpose of
 321      * inheritance of scoped value bindings.
 322      *
 323      * @param name the name of the task scope, can be null
 324      * @param factory the thread factory
 325      */
 326     public StructuredTaskScope(String name, ThreadFactory factory) {
 327         this.factory = Objects.requireNonNull(factory, "'factory' is null");
 328         this.flock = ThreadFlock.open(name);
 329     }
 330 
 331     /**
 332      * Creates an unnamed structured task scope that creates virtual threads. The task
 333      * scope is owned by the current thread.
 334      *
 335      * <p> This constructor is equivalent to invoking the 2-arg constructor with a name
 336      * of {@code null} and a thread factory that creates virtual threads.


 337      */
 338     public StructuredTaskScope() {

 339         this.factory = Thread.ofVirtual().factory();
 340         this.flock = ThreadFlock.open(null);
 341     }
 342 
 343     /**
 344      * Throws WrongThreadException if the current thread is not the owner.
 345      */
 346     private void ensureOwner() {
 347         if (Thread.currentThread() != flock.owner())
 348             throw new WrongThreadException("Current thread not owner");
 349     }
 350 
 351     /**
 352      * Throws WrongThreadException if the current thread is not the owner
 353      * or a thread contained in the tree.
 354      */
 355     private void ensureOwnerOrContainsThread() {
 356         Thread currentThread = Thread.currentThread();
 357         if (currentThread != flock.owner() && !flock.containsThread(currentThread))
 358             throw new WrongThreadException("Current thread not owner or thread in the tree");
< prev index next >