1 /*
   2  * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.util.concurrent;
  26 
  27 import java.time.Duration;
  28 import java.util.function.Predicate;
  29 import java.util.function.Supplier;
  30 import java.util.function.UnaryOperator;
  31 import java.util.stream.Stream;
  32 import jdk.internal.javac.PreviewFeature;
  33 
  34 /**
  35  * An API for <em>structured concurrency</em>. {@code StructuredTaskScope} supports cases
  36  * where execution of a <em>task</em> (a unit of work) splits into several concurrent
  37  * subtasks, and where the subtasks must complete before the task continues. A {@code
  38  * StructuredTaskScope} can be used to ensure that the lifetime of a concurrent operation
  39  * is confined by a <em>syntax block</em>, similar to that of a sequential operation in
  40  * structured programming.
  41  *
  42  * <p> {@code StructuredTaskScope} defines the static method {@link #open() open} to open
  43  * a new {@code StructuredTaskScope} and the {@link #close() close} method to close it.
  44  * The API is designed to be used with the {@code try}-with-resources statement where
  45  * the {@code StructuredTaskScope} is opened as a resource and then closed automatically.
  46  * The code inside the block uses the {@link #fork(Callable) fork} method to fork subtasks.
  47  * After forking, it uses the {@link #join() join} method to wait for all subtasks to
  48  * finish (or some other outcome) as a single operation. Forking a subtask starts a new
  49  * {@link Thread} to run the subtask. The thread executing the task does not continue
  50  * beyond the {@code close} method until all threads started to execute subtasks have finished.
  51  * To ensure correct usage, the {@code fork}, {@code join} and {@code close} methods may
  52  * only be invoked by the <em>owner thread</em> (the thread that opened the {@code
  53  * StructuredTaskScope}), the {@code fork} method may not be called after {@code join},
  54  * the {@code join} method may only be invoked once, and the {@code close} method throws
  55  * an exception after closing if the owner did not invoke the {@code join} method after
  56  * forking subtasks.
  57  *
  58  * <p> As a first example, consider a task that splits into two subtasks to concurrently
  59  * fetch resources from two URL locations "left" and "right". Both subtasks may complete
  60  * successfully, one subtask may succeed and the other may fail, or both subtasks may
  61  * fail. The task in this example is interested in the successful result from both
  62  * subtasks. It waits in the {@link #join() join} method for both subtasks to complete
  63  * successfully or for either subtask to fail.
  64  * {@snippet lang=java :
  65  *    // @link substring="open" target="#open()" :
  66  *    try (var scope = StructuredTaskScope.open()) {
  67  *
  68  *        // @link substring="fork" target="#fork(Callable)" :
  69  *        Subtask<String> subtask1 = scope.fork(() -> query(left));
  70  *        Subtask<Integer> subtask2 = scope.fork(() -> query(right));
  71  *
  72  *        // throws if either subtask fails
  73  *        scope.join();  // @link substring="join" target="#join()"
  74  *
  75  *        // both subtasks completed successfully
  76  *        // @link substring="get" target="Subtask#get()" :
  77  *        return new MyResult(subtask1.get(), subtask2.get());
  78  *
  79  *    // @link substring="close" target="#close()" :
  80  *    } // close
  81  * }
  82  *
  83  * <p> If both subtasks complete successfully then the {@code join} method completes
  84  * normally and the task uses the {@link Subtask#get() Subtask.get()} method to get
  85  * the result of each subtask. If one of the subtasks fails then the other subtask is
  86  * cancelled (this will {@linkplain Thread#interrupt() interrupt} the thread executing the
  87  * other subtask) and the {@code join} method throws {@link FailedException} with the
  88  * exception from the failed subtask as the {@linkplain Throwable#getCause() cause}.
  89  *
  90  * <p> To allow for cancellation, subtasks must be coded so that they finish as soon as
  91  * possible when interrupted. Subtasks that do not respond to interrupt, e.g. block on
  92  * methods that are not interruptible, may delay the closing of a scope indefinitely. The
  93  * {@link #close() close} method always waits for threads executing subtasks to finish,
  94  * even if the scope is cancelled, so execution cannot continue beyond the {@code close}
  95  * method until the interrupted threads finish.
  96  *
  97  * <p> In the example, the subtasks produce results of different types ({@code String} and
  98  * {@code Integer}). In other cases the subtasks may all produce results of the same type.
  99  * If the example had used {@code StructuredTaskScope.<String>open()} then it could
 100  * only be used to fork subtasks that return a {@code String} result.
 101  *
 102  * <h2>Joiners</h2>
 103  *
 104  * <p> In the example above, the task fails if any subtask fails. If all subtasks
 105  * succeed then the {@code join} method completes normally. Other policy and outcome is
 106  * supported by creating a {@code StructuredTaskScope} with a {@link Joiner} that
 107  * implements the desired policy. A {@code Joiner} handles subtask completion and produces
 108  * the outcome for the {@link #join() join} method. In the example above, {@code join}
 109  * returns {@code null}. Depending on the {@code Joiner}, {@code join} may return a
 110  * result, a stream of elements, or some other object. The {@code Joiner} interface defines
 111  * factory methods to create {@code Joiner}s for some common cases.
 112  *
 113  * <p> A {@code Joiner} may <a id="Cancallation">cancel</a> the scope (sometimes called
 114  * "short-circuiting") when some condition is reached that does not require the result of
 115  * subtasks that are still executing. Cancelling the scope prevents new threads from being
 116  * started to execute further subtasks, {@linkplain Thread#interrupt() interrupts} the
 117  * threads executing subtasks that have not completed, and causes the {@code join} method
 118  * to wakeup with the outcome (result or exception). In the above example, the outcome is
 119  * that {@code join} completes with a result of {@code null} when all subtasks succeed.
 120  * The scope is cancelled if any of the subtasks fail and {@code join} throws {@code
 121  * FailedException} with the exception from the failed subtask as the cause. Other {@code
 122  * Joiner} implementations may cancel the scope for other reasons.
 123  *
 124  * <p> Now consider another example that splits into two subtasks. In this example,
 125  * each subtask produces a {@code String} result and the task is only interested in
 126  * the result from the first subtask to complete successfully. The example uses {@link
 127  * Joiner#anySuccessfulResultOrThrow() Joiner.anySuccessfulResultOrThrow()} to
 128  * create a {@code Joiner} that makes available the result of the first subtask to
 129  * complete successfully. The type parameter in the example is "{@code String}" so that
 130  * only subtasks that return a {@code String} can be forked.
 131  * {@snippet lang=java :
 132  *    // @link substring="open" target="#open(Joiner)" :
 133  *    try (var scope = StructuredTaskScope.open(Joiner.<String>anySuccessfulResultOrThrow())) {
 134  *
 135  *        scope.fork(callable1);
 136  *        scope.fork(callable2);
 137  *
 138  *        // throws if both subtasks fail
 139  *        String firstResult = scope.join();
 140  *
 141  *    }
 142  * }
 143  *
 144  * <p> In the example, the task forks the two subtasks, then waits in the {@code
 145  * join} method for either subtask to complete successfully or for both subtasks to fail.
 146  * If one of the subtasks completes successfully then the {@code Joiner} causes the other
 147  * subtask to be cancelled (this will interrupt the thread executing the subtask), and
 148  * the {@code join} method returns the result from the successful subtask. Cancelling the
 149  * other subtask avoids the task waiting for a result that it doesn't care about. If
 150  * both subtasks fail then the {@code join} method throws {@code FailedException} with the
 151  * exception from one of the subtasks as the {@linkplain Throwable#getCause() cause}.
 152  *
 153  * <p> Whether code uses the {@code Subtask} returned from {@code fork} will depend on
 154  * the {@code Joiner} and usage. Some {@code Joiner} implementations are suited to subtasks
 155  * that return results of the same type and where the {@code join} method returns a result
 156  * for the task to use. Code that forks subtasks that return results of different
 157  * types, and uses a {@code Joiner} such as {@code Joiner.awaitAllSuccessfulOrThrow()} that
 158  * does not return a result, will use {@link Subtask#get() Subtask.get()} after joining.
 159  *
 160  * <h2>Exception handling</h2>
 161  *
 162  * <p> A {@code StructuredTaskScope} is opened with a {@link Joiner Joiner} that
 163  * handles subtask completion and produces the outcome for the {@link #join() join} method.
 164  * In some cases, the outcome will be a result, in other cases it will be an exception.
 165  * If the outcome is an exception then the {@code join} method throws {@link
 166  * FailedException} with the exception as the {@linkplain Throwable#getCause()
 167  * cause}. For many {@code Joiner} implementations, the exception will be an exception
 168  * thrown by a subtask that failed. In the case of {@link Joiner#allSuccessfulOrThrow()
 169  * allSuccessfulOrThrow} and {@link Joiner#awaitAllSuccessfulOrThrow() awaitAllSuccessfulOrThrow}
 170  * for example, the exception is from the first subtask to fail.
 171  *
 172  * <p> Many of the details for how exceptions are handled will depend on usage. In some
 173  * cases it may be useful to add a {@code catch} block to the {@code try}-with-resources
 174  * statement to catch {@code FailedException}. The exception handling may use {@code
 175  * instanceof} with pattern matching to handle specific causes.
 176  * {@snippet lang=java :
 177  *    try (var scope = StructuredTaskScope.open()) {
 178  *
 179  *        ..
 180  *
 181  *    } catch (StructuredTaskScope.FailedException e) {
 182  *
 183  *        Throwable cause = e.getCause();
 184  *        switch (cause) {
 185  *            case IOException ioe -> ..
 186  *            default -> ..
 187  *        }
 188  *
 189  *    }
 190  * }
 191  * In other cases it may not be useful to catch {@code FailedException} but instead leave
 192  * it to propagate to the configured {@linkplain Thread.UncaughtExceptionHandler uncaught
 193  * exception handler} for logging purposes.
 194  *
 195  * <p> For cases where a specific exception triggers the use of a default result then it
 196  * may be more appropriate to handle this in the subtask itself rather than the subtask
 197  * failing and the scope owner handling the exception.
 198  *
 199  * <h2>Configuration</h2>
 200  *
 201  * A {@code StructuredTaskScope} is opened with {@linkplain Configuration configuration}
 202  * that consists of a {@link ThreadFactory} to create threads, an optional name for
 203  * monitoring and management purposes, and an optional timeout.
 204  *
 205  * <p> The {@link #open()} and {@link #open(Joiner)} methods create a {@code StructuredTaskScope}
 206  * with the <a id="DefaultConfiguration"> <em>default configuration</em></a>. The default
 207  * configuration has a {@code ThreadFactory} that creates unnamed {@linkplain
 208  * Thread##virtual-threads virtual threads}, is unnamed for monitoring and management
 209  * purposes, and has no timeout.
 210  *
 211  * <p> The 2-arg {@link #open(Joiner, UnaryOperator) open} method can be used to create a
 212  * {@code StructuredTaskScope} that uses a different {@code ThreadFactory}, has a name for
 213  * the purposes of monitoring and management, or has a timeout that cancels the scope if
 214  * the timeout expires before or while waiting for subtasks to complete. The {@code open}
 215  * method is called with a {@linkplain UnaryOperator operator} that is applied to the default
 216  * configuration and returns a {@link Configuration Configuration} for the
 217  * {@code StructuredTaskScope} under construction.
 218  *
 219  * <p> The following example opens a new {@code StructuredTaskScope} with a {@code
 220  * ThreadFactory} that creates virtual threads {@linkplain Thread#setName(String) named}
 221  * "duke-0", "duke-1" ...
 222  * {@snippet lang = java:
 223  *    // @link substring="name" target="Thread.Builder#name(String, long)" :
 224  *    ThreadFactory factory = Thread.ofVirtual().name("duke-", 0).factory();
 225  *
 226  *    // @link substring="withThreadFactory" target="Configuration#withThreadFactory(ThreadFactory)" :
 227  *    try (var scope = StructuredTaskScope.open(joiner, cf -> cf.withThreadFactory(factory))) {
 228  *
 229  *        scope.fork( .. );   // runs in a virtual thread with name "duke-0"
 230  *        scope.fork( .. );   // runs in a virtual thread with name "duke-1"
 231  *
 232  *        scope.join();
 233  *
 234  *     }
 235  *}
 236  *
 237  * <p> A second example sets a timeout, represented by a {@link Duration}. The timeout
 238  * starts when the new scope is opened. If the timeout expires before the {@code join}
 239  * method has completed then the scope is {@linkplain ##Cancallation cancelled} (this
 240  * interrupts the threads executing the two subtasks) and the {@code Joiner}'s {@link
 241  * Joiner#onTimeout() onTimeout} method is invoked to throw {@link TimeoutException
 242  * TimeoutException}.
 243  * {@snippet lang=java :
 244  *    Duration timeout = Duration.ofSeconds(10);
 245  *
 246  *    // @link substring="allSuccessfulOrThrow" target="Joiner#allSuccessfulOrThrow()" :
 247  *    try (var scope = StructuredTaskScope.open(Joiner.<String>allSuccessfulOrThrow(),
 248  *    // @link substring="withTimeout" target="Configuration#withTimeout(Duration)" :
 249  *                                              cf -> cf.withTimeout(timeout))) {
 250  *
 251  *        scope.fork(callable1);
 252  *        scope.fork(callable2);
 253  *
 254  *        List<String> result = scope.join()
 255  *                                   .map(Subtask::get)
 256  *                                   .toList();
 257  *
 258  *   }
 259  * }
 260  *
 261  * <h2>Inheritance of scoped value bindings</h2>
 262  *
 263  * {@link ScopedValue} supports the execution of a method with a {@code ScopedValue} bound
 264  * to a value for the bounded period of execution of the method by the <em>current thread</em>.
 265  * It allows a value to be safely and efficiently shared to methods without using method
 266  * parameters.
 267  *
 268  * <p> When used in conjunction with a {@code StructuredTaskScope}, a {@code ScopedValue}
 269  * can also safely and efficiently share a value to methods executed by subtasks forked
 270  * in the scope. When a {@code ScopedValue} object is bound to a value in the thread
 271  * executing the task then that binding is inherited by the threads created to
 272  * execute the subtasks. The thread executing the task does not continue beyond the
 273  * {@link #close() close} method until all threads executing the subtasks have finished.
 274  * This ensures that the {@code ScopedValue} is not reverted to being {@linkplain
 275  * ScopedValue#isBound() unbound} (or its previous value) while subtasks are executing.
 276  * In addition to providing a safe and efficient means to inherit a value into subtasks,
 277  * the inheritance allows sequential code using {@code ScopedValue} be refactored to use
 278  * structured concurrency.
 279  *
 280  * <p> To ensure correctness, opening a new {@code StructuredTaskScope} captures the
 281  * current thread's scoped value bindings. These are the scoped values bindings that are
 282  * inherited by the threads created to execute subtasks in the scope. Forking a
 283  * subtask checks that the bindings in effect at the time that the subtask is forked
 284  * match the bindings when the {@code StructuredTaskScope} was created. This check ensures
 285  * that a subtask does not inherit a binding that is reverted in the task before the
 286  * subtask has completed.
 287  *
 288  * <p> A {@code ScopedValue} that is shared across threads requires that the value be an
 289  * immutable object or for all access to the value to be appropriately synchronized.
 290  *
 291  * <p> The following example demonstrates the inheritance of scoped value bindings. The
 292  * scoped value USERNAME is bound to the value "duke" for the bounded period of a lambda
 293  * expression by the thread executing it. The code in the block opens a {@code
 294  * StructuredTaskScope} and forks two subtasks, it then waits in the {@code join} method
 295  * and aggregates the results from both subtasks. If code executed by the threads
 296  * running subtask1 and subtask2 uses {@link ScopedValue#get()}, to get the value of
 297  * USERNAME, then value "duke" will be returned.
 298  * {@snippet lang=java :
 299  *     // @link substring="newInstance" target="ScopedValue#newInstance()" :
 300  *     private static final ScopedValue<String> USERNAME = ScopedValue.newInstance();
 301  *
 302  *     // @link substring="where" target="ScopedValue#where(ScopedValue, Object)" :
 303  *     MyResult result = ScopedValue.where(USERNAME, "duke").call(() -> {
 304  *
 305  *         try (var scope = StructuredTaskScope.open()) {
 306  *
 307  *             Subtask<String> subtask1 = scope.fork( .. );    // inherits binding
 308  *             Subtask<Integer> subtask2 = scope.fork( .. );   // inherits binding
 309  *
 310  *             scope.join();
 311  *             return new MyResult(subtask1.get(), subtask2.get());
 312  *         }
 313  *
 314  *     });
 315  * }
 316  *
 317  * <p> A scoped value inherited into a subtask may be {@linkplain ScopedValue##rebind
 318  * rebound} to a new value in the subtask for the bounded execution of some method executed
 319  * in the subtask. When the method completes, the value of the {@code ScopedValue} reverts
 320  * to its previous value, the value inherited from the thread executing the task.
 321  *
 322  * <p> A subtask may execute code that itself opens a new {@code StructuredTaskScope}.
 323  * A task executing in thread T1 opens a {@code StructuredTaskScope} and forks a
 324  * subtask that runs in thread T2. The scoped value bindings captured when T1 opens the
 325  * scope are inherited into T2. The subtask (in thread T2) executes code that opens a
 326  * new {@code StructuredTaskScope} and forks a subtask that runs in thread T3. The scoped
 327  * value bindings captured when T2 opens the scope are inherited into T3. These
 328  * include (or may be the same) as the bindings that were inherited from T1. In effect,
 329  * scoped values are inherited into a tree of subtasks, not just one level of subtask.
 330  *
 331  * <h2>Memory consistency effects</h2>
 332  *
 333  * <p> Actions in the owner thread of a {@code StructuredTaskScope} prior to {@linkplain
 334  * #fork forking} of a subtask {@linkplain java.util.concurrent##MemoryVisibility
 335  * <i>happen-before</i>} any actions taken by that subtask, which in turn
 336  * <i>happen-before</i> the subtask result is {@linkplain Subtask#get() retrieved}.
 337  *
 338  * <h2>General exceptions</h2>
 339  *
 340  * <p> Unless otherwise specified, passing a {@code null} argument to a method in this
 341  * class will cause a {@link NullPointerException} to be thrown.
 342  *
 343  * @param <T> the result type of subtasks executed in the scope
 344  * @param <R> the result type of the scope
 345  *
 346  * @jls 17.4.5 Happens-before Order
 347  * @since 21
 348  */
 349 @PreviewFeature(feature = PreviewFeature.Feature.STRUCTURED_CONCURRENCY)
 350 public sealed interface StructuredTaskScope<T, R>
 351         extends AutoCloseable
 352         permits StructuredTaskScopeImpl {
 353 
 354     /**
 355      * Represents a subtask forked with {@link #fork(Callable)} or {@link #fork(Runnable)}.
 356      *
 357      * <p> Code that forks subtasks can use the {@link #get() get()} method after {@linkplain
 358      * #join() joining} to obtain the result of a subtask that completed successfully. It
 359      * can use the {@link #exception()} method to obtain the exception thrown by a subtask
 360      * that failed.
 361      *
 362      * @param <T> the result type
 363      * @since 21
 364      */
 365     @PreviewFeature(feature = PreviewFeature.Feature.STRUCTURED_CONCURRENCY)
 366     sealed interface Subtask<T> extends Supplier<T> permits StructuredTaskScopeImpl.SubtaskImpl {
 367         /**
 368          * Represents the state of a subtask.
 369          * @see Subtask#state()
 370          * @since 21
 371          */
 372         @PreviewFeature(feature = PreviewFeature.Feature.STRUCTURED_CONCURRENCY)
 373         enum State {
 374             /**
 375              * The subtask result or exception is not available. This state indicates that
 376              * the subtask was forked but has not completed, it completed after the scope
 377              * was cancelled, or it was forked after the scoped was cancelled (in which
 378              * case a thread was not created to execute the subtask).
 379              */
 380             UNAVAILABLE,
 381             /**
 382              * The subtask completed successfully. The {@link Subtask#get() Subtask.get()}
 383              * method can be used to get the result. This is a terminal state.
 384              */
 385             SUCCESS,
 386             /**
 387              * The subtask failed with an exception. The {@link Subtask#exception()
 388              * Subtask.exception()} method can be used to get the exception. This is a
 389              * terminal state.
 390              */
 391             FAILED,
 392         }
 393 
 394         /**
 395          * {@return the subtask state}
 396          */
 397         State state();
 398 
 399         /**
 400          * Returns the result of this subtask if it completed successfully. If the subtask
 401          * was forked with {@link #fork(Callable) fork(Callable)} then the result from the
 402          * {@link Callable#call() call} method is returned. If the subtask was forked with
 403          * {@link #fork(Runnable) fork(Runnable)} then {@code null} is returned.
 404          *
 405          * <p> Code executing in the scope owner thread can use this method to get the
 406          * result of a successful subtask only after it has {@linkplain #join() joined}.
 407          *
 408          * <p> Code executing in the {@code Joiner} {@link Joiner#onComplete(Subtask)
 409          * onComplete} method should test that the {@linkplain #state() subtask state} is
 410          * {@link State#SUCCESS SUCCESS} before using this method to get the result.
 411          *
 412          * @return the possibly-null result
 413          * @throws IllegalStateException if the subtask has not completed, did not complete
 414          * successfully, or the current thread is the scope owner invoking this
 415          * method before {@linkplain #join() joining}
 416          * @see State#SUCCESS
 417          */
 418         T get();
 419 
 420         /**
 421          * {@return the exception or error thrown by this subtask if it failed}
 422          * If the subtask was forked with {@link #fork(Callable) fork(Callable)} then the
 423          * exception or error thrown by the {@link Callable#call() call} method is returned.
 424          * If the subtask was forked with {@link #fork(Runnable) fork(Runnable)} then the
 425          * exception or error thrown by the {@link Runnable#run() run} method is returned.
 426          *
 427          * <p> Code executing in the scope owner thread can use this method to get the
 428          * exception thrown by a failed subtask only after it has {@linkplain #join() joined}.
 429          *
 430          * <p> Code executing in a {@code Joiner} {@link Joiner#onComplete(Subtask)
 431          * onComplete} method should test that the {@linkplain #state() subtask state} is
 432          * {@link State#FAILED FAILED} before using this method to get the exception.
 433          *
 434          * @throws IllegalStateException if the subtask has not completed, completed with
 435          * a result, or the current thread is the scope owner invoking this method
 436          * before {@linkplain #join() joining}
 437          * @see State#FAILED
 438          */
 439         Throwable exception();
 440     }
 441 
 442     /**
 443      * An object used with a {@link StructuredTaskScope} to handle subtask completion and
 444      * produce the result for the scope owner waiting in the {@link #join() join} method
 445      * for subtasks to complete.
 446      *
 447      * <p> Joiner defines static methods to create {@code Joiner} objects for common cases:
 448      * <ul>
 449      *   <li> {@link #allSuccessfulOrThrow() allSuccessfulOrThrow()} creates a {@code Joiner}
 450      *   that yields a stream of the completed subtasks for {@code join} to return when
 451      *   all subtasks complete successfully. It cancels the scope and causes {@code join}
 452      *   to throw if any subtask fails.
 453      *   <li> {@link #anySuccessfulResultOrThrow() anySuccessfulResultOrThrow()} creates a
 454      *   {@code Joiner} that yields the result of the first subtask to succeed for {@code
 455      *   join} to return. It causes {@code join} to throw if all subtasks fail.
 456      *   <li> {@link #awaitAllSuccessfulOrThrow() awaitAllSuccessfulOrThrow()} creates a
 457      *   {@code Joiner} that waits for all successful subtasks. It cancels the scope and
 458      *   causes {@code join} to throw if any subtask fails.
 459      *   <li> {@link #awaitAll() awaitAll()} creates a {@code Joiner} that waits for all
 460      *   subtasks to complete. It does not cancel the scope or cause {@code join} to throw.
 461      * </ul>
 462      *
 463      * <p> In addition to the methods to create {@code Joiner} objects for common cases,
 464      * the {@link #allUntil(Predicate) allUntil(Predicate)} method is defined to create a
 465      * {@code Joiner} that yields a stream of all subtasks. It is created with a {@link
 466      * Predicate Predicate} that determines if the scope should continue or be cancelled.
 467      * This {@code Joiner} can be built upon to create custom policies that cancel the
 468      * scope based on some condition.
 469      *
 470      * <p> More advanced policies can be developed by implementing the {@code Joiner}
 471      * interface. The {@link #onFork(Subtask)} method is invoked when subtasks are forked.
 472      * The {@link #onComplete(Subtask)} method is invoked when subtasks complete with a
 473      * result or exception. These methods return a {@code boolean} to indicate if the scope
 474      * should be cancelled. These methods can be used to collect subtasks, results, or
 475      * exceptions, and control when to cancel the scope. The {@link #result()} method
 476      * must be implemented to produce the result (or exception) for the {@code join}
 477      * method.
 478      *
 479      * <p> If a {@code StructuredTaskScope} is opened with a {@linkplain
 480      * Configuration#withTimeout(Duration) timeout}, and the timeout expires before or
 481      * while waiting in {@link StructuredTaskScope#join() join()}, then the scope is
 482      * {@linkplain StructuredTaskScope##Cancallation cancelled}, and the {@code Joiners}'s
 483      * {@link #onTimeout()} method is invoked to notify the {@code Joiner} and optionally
 484      * throw {@link TimeoutException TimeoutException}. If the {@code onTimeout()} method
 485      * does not throw then the {@code join()} method will invoke the {@link #result()}
 486      * method to produce a result. This result may be based on the outcome of subtasks
 487      * that completed before the timeout expired.
 488      *
 489      * <p> Unless otherwise specified, passing a {@code null} argument to a method
 490      * in this class will cause a {@link NullPointerException} to be thrown.
 491      *
 492      * @implSpec Implementations of this interface must be thread safe. The {@link
 493      * #onComplete(Subtask)} method defined by this interface may be invoked by several
 494      * threads concurrently. The {@link #onTimeout()} method may be invoked at around
 495      * the same time that subtasks complete.
 496      *
 497      * @apiNote It is very important that a new {@code Joiner} object is created for each
 498      * {@code StructuredTaskScope}. {@code Joiner} objects should never be shared with
 499      * different scopes or re-used after a task is closed.
 500      *
 501      * <p> Designing a {@code Joiner} should take into account the code at the use-site
 502      * where the results from the {@link StructuredTaskScope#join() join} method are
 503      * processed. It should be clear what the {@code Joiner} does vs. the application
 504      * code at the use-site. In general, the {@code Joiner} implementation is not the
 505      * place for "business logic". A {@code Joiner} should be designed to be as general
 506      * purpose as possible.
 507      *
 508      * @param <T> the result type of subtasks executed in the scope
 509      * @param <R> the result type of the scope
 510      * @since 25
 511      * @see #open(Joiner)
 512      */
 513     @PreviewFeature(feature = PreviewFeature.Feature.STRUCTURED_CONCURRENCY)
 514     interface Joiner<T, R> {
 515         /**
 516          * Invoked by {@link #fork(Callable) fork(Callable)} and {@link #fork(Runnable)
 517          * fork(Runnable)} when forking a subtask. The method is invoked before a thread
 518          * is created to run the subtask.
 519          *
 520          * @implSpec The default implementation throws {@code NullPointerException} if the
 521          * subtask is {@code null}. It throws {@code IllegalArgumentException} if the
 522          * subtask is not in the {@link Subtask.State#UNAVAILABLE UNAVAILABLE} state, it
 523          * otherwise returns {@code false}.
 524          *
 525          * @apiNote This method is invoked by the {@code fork} methods. It should not be
 526          * invoked directly.
 527          *
 528          * @param subtask the subtask
 529          * @return {@code true} to cancel the scope, otherwise {@code false}
 530          */
 531         default boolean onFork(Subtask<? extends T> subtask) {
 532             if (subtask.state() != Subtask.State.UNAVAILABLE) {
 533                 throw new IllegalArgumentException("Subtask not in UNAVAILABLE state");
 534             }
 535             return false;
 536         }
 537 
 538         /**
 539          * Invoked by the thread started to execute a subtask after the subtask completes
 540          * successfully or fails with an exception. This method is not invoked if a
 541          * subtask completes after the scope is cancelled.
 542          *
 543          * @implSpec The default implementation throws {@code NullPointerException} if the
 544          * subtask is {@code null}. It throws {@code IllegalArgumentException} if the
 545          * subtask is not in the {@link Subtask.State#SUCCESS SUCCESS} or {@link
 546          * Subtask.State#FAILED FAILED} state, it otherwise returns {@code false}.
 547          *
 548          * @apiNote This method is invoked by subtasks when they complete. It should not
 549          * be invoked directly.
 550          *
 551          * @param subtask the subtask
 552          * @return {@code true} to cancel the scope, otherwise {@code false}
 553          */
 554         default boolean onComplete(Subtask<? extends T> subtask) {
 555             if (subtask.state() == Subtask.State.UNAVAILABLE) {
 556                 throw new IllegalArgumentException("Subtask has not completed");
 557             }
 558             return false;
 559         }
 560 
 561         /**
 562          * Invoked by the {@link #join() join()} method if the scope was opened with a
 563          * timeout, and the timeout expires before or while waiting in the {@code join}
 564          * method.
 565          *
 566          * @implSpec The default implementation throws {@link TimeoutException TimeoutException}.
 567          *
 568          * @apiNote This method is intended for {@code Joiner} implementations that do not
 569          * throw {@link TimeoutException TimeoutException}, or require a notification when
 570          * the timeout expires before or while waiting in {@code join}.
 571          *
 572          * <p> This method is invoked by the {@code join} method. It should not be
 573          * invoked directly.
 574          *
 575          * @throws TimeoutException for {@code join} to throw
 576          * @since 26
 577          */
 578         default void onTimeout() {
 579             throw new TimeoutException();
 580         }
 581 
 582         /**
 583          * Invoked by the {@link #join() join()} method to produce the result (or exception)
 584          * after waiting for all subtasks to complete or the scope cancelled. The result
 585          * from this method is returned by the {@code join} method. If this method throws,
 586          * then {@code join} throws {@link FailedException} with the exception thrown by
 587          * this method as the cause.
 588          *
 589          * <p> In normal usage, this method will be called at most once by the {@code join}
 590          * method to produce the result (or exception). The behavior of this method when
 591          * invoked directly, and invoked more than once, is undefined. Where possible, an
 592          * implementation should return an equal result (or throw the same exception) on
 593          * second or subsequent calls to produce the outcome.
 594          *
 595          * @apiNote This method is invoked by the {@code join} method. It should not be
 596          * invoked directly.
 597          *
 598          * @return the result
 599          * @throws Throwable the exception
 600          */
 601         R result() throws Throwable;
 602 
 603         /**
 604          * {@return a new Joiner object that yields a stream of all subtasks when all
 605          * subtasks complete successfully}
 606          * The {@code Joiner} {@linkplain StructuredTaskScope##Cancallation cancels}
 607          * the scope and causes {@code join} to throw if any subtask fails.
 608          *
 609          * <p> If all subtasks complete successfully then the joiner's {@link
 610          * Joiner#result()} method returns a stream of all subtasks, in the order that they
 611          * were forked, for the {@link StructuredTaskScope#join() join()} to return. If
 612          * the scope was opened with a {@linkplain Configuration#withTimeout(Duration)
 613          * timeout}, and the timeout expires before or while waiting for all subtasks to
 614          * complete, then the {@code join} method throws {@code TimeoutException}.
 615          *
 616          * @apiNote Joiners returned by this method are suited to cases where all subtasks
 617          * return a result of the same type. Joiners returned by {@link
 618          * #awaitAllSuccessfulOrThrow()} are suited to cases where the subtasks return
 619          * results of different types.
 620          *
 621          * @param <T> the result type of subtasks
 622          */
 623         static <T> Joiner<T, Stream<Subtask<T>>> allSuccessfulOrThrow() {
 624             return new Joiners.AllSuccessful<>();
 625         }
 626 
 627         /**
 628          * {@return a new Joiner object that yields the result of any subtask that
 629          * completed successfully}
 630          * The {@code Joiner} causes {@code join} to throw if all subtasks fail.
 631          *
 632          * <p> The joiner's {@link Joiner#result()} method returns the result of a subtask,
 633          * that completed successfully, for the {@link StructuredTaskScope#join() join()}
 634          * to return. If all subtasks fail then the {@code result} method throws the
 635          * exception from one of the failed subtasks. The {@code result} method throws
 636          * {@code NoSuchElementException} if no subtasks were forked. If the scope was
 637          * opened with a {@linkplain Configuration#withTimeout(Duration) timeout}, and
 638          * the timeout expires before or while waiting for any subtask to complete
 639          * successfully, then the {@code join} method throws {@code TimeoutException}.
 640          *
 641          * @param <T> the result type of subtasks
 642          */
 643         static <T> Joiner<T, T> anySuccessfulResultOrThrow() {
 644             return new Joiners.AnySuccessful<>();
 645         }
 646 
 647         /**
 648          * {@return a new Joiner object that waits for subtasks to complete successfully}
 649          * The {@code Joiner} {@linkplain StructuredTaskScope##Cancallation cancels}
 650          * the scope and causes {@code join} to throw if any subtask fails.
 651          *
 652          * <p> The joiner's {@link Joiner#result() result} method returns {@code null}
 653          * if all subtasks complete successfully, or throws the exception from the first
 654          * subtask to fail. If the scope was opened with a {@linkplain
 655          * Configuration#withTimeout(Duration) timeout}, and the timeout expires before or
 656          * while waiting for all subtasks to complete, then the {@code join} method throws
 657          * {@code TimeoutException}.
 658          *
 659          * @apiNote Joiners returned by this method are suited to cases where subtasks
 660          * return results of different types. Joiners returned by {@link #allSuccessfulOrThrow()}
 661          * are suited to cases where the subtasks return a result of the same type.
 662          *
 663          * @param <T> the result type of subtasks
 664          */
 665         static <T> Joiner<T, Void> awaitAllSuccessfulOrThrow() {
 666             return new Joiners.AwaitSuccessful<>();
 667         }
 668 
 669         /**
 670          * {@return a new Joiner object that waits for all subtasks to complete}
 671          * The {@code Joiner} does not cancel the scope if a subtask fails.
 672          *
 673          * <p> The joiner's {@link Joiner#result() result} method returns {@code null}.
 674          * If the scope was opened with a {@linkplain Configuration#withTimeout(Duration)
 675          * timeout}, and the timeout expires before or while waiting for all subtasks to
 676          * complete, then the {@code join} method throws {@code TimeoutException}.
 677          *
 678          * @apiNote This Joiner is useful for cases where subtasks make use of
 679          * <em>side-effects</em> rather than return results or fail with exceptions.
 680          * The {@link #fork(Runnable) fork(Runnable)} method can be used to fork subtasks
 681          * that do not return a result.
 682          *
 683          * <p> This Joiner can also be used for <em>fan-in</em> scenarios where subtasks
 684          * are forked to handle incoming connections and the number of subtasks is unbounded.
 685          * In this example, the thread executing the {@code acceptLoop} method will only
 686          * stop when interrupted or the listener socket is closed asynchronously.
 687          * {@snippet lang=java :
 688          *   void acceptLoop(ServerSocket listener) throws IOException, InterruptedException {
 689          *       try (var scope = StructuredTaskScope.open(Joiner.<Socket>awaitAll())) {
 690          *           while (true) {
 691          *               Socket socket = listener.accept();
 692          *               scope.fork(() -> handle(socket));
 693          *           }
 694          *       }
 695          *   }
 696          * }
 697          *
 698          * @param <T> the result type of subtasks
 699          */
 700         static <T> Joiner<T, Void> awaitAll() {
 701             // ensure that new Joiner object is returned
 702             return new Joiner<T, Void>() {
 703                 @Override
 704                 public Void result() {
 705                     return null;
 706                 }
 707             };
 708         }
 709 
 710         /**
 711          * {@return a new Joiner object that yields a stream of all subtasks when all
 712          * subtasks complete or a predicate returns {@code true} to cancel the scope}
 713          *
 714          * <p> The joiner's {@link #onComplete(Subtask)} method invokes the predicate's
 715          * {@link Predicate#test(Object) test} method with the subtask that completed
 716          * successfully or failed with an exception. If the {@code test} method
 717          * returns {@code true} then {@linkplain StructuredTaskScope##Cancallation
 718          * the scope is cancelled}. The {@code test} method must be thread safe as it
 719          * may be invoked concurrently from several threads. If the {@code test} method
 720          * completes with an exception or error, then the thread that executed the subtask
 721          * invokes the {@linkplain Thread.UncaughtExceptionHandler uncaught exception handler}
 722          * with the exception or error before the thread terminates.
 723          *
 724          * <p> The joiner's {@link #result()} method returns the stream of all subtasks,
 725          * in fork order. The stream may contain subtasks that have completed
 726          * (in {@link Subtask.State#SUCCESS SUCCESS} or {@link Subtask.State#FAILED FAILED}
 727          * state) or subtasks in the {@link Subtask.State#UNAVAILABLE UNAVAILABLE} state
 728          * if the scope was cancelled before all subtasks were forked or completed.
 729          *
 730          * <p> The joiner's {@link #onTimeout()} method does nothing. If configured with
 731          * a {@linkplain Configuration#withTimeout(Duration) timeout}, and the timeout
 732          * expires before or while waiting in {@link StructuredTaskScope#join() join},
 733          * then the {@link #result()} method returns the stream of all subtasks.
 734          * Subtasks that did not complete before the timeout expired will be in the
 735          * {@link Subtask.State#UNAVAILABLE UNAVAILABLE} state.
 736          *
 737          * <p> The following example uses this method to create a {@code Joiner} that
 738          * {@linkplain StructuredTaskScope##Cancallation cancels} the scope when two or
 739          * more subtasks fail.
 740          * {@snippet lang=java :
 741          *    class CancelAfterTwoFailures<T> implements Predicate<Subtask<? extends T>> {
 742          *         private final AtomicInteger failedCount = new AtomicInteger();
 743          *         @Override
 744          *         public boolean test(Subtask<? extends T> subtask) {
 745          *             return subtask.state() == Subtask.State.FAILED
 746          *                     && failedCount.incrementAndGet() >= 2;
 747          *         }
 748          *     }
 749          *
 750          *     var joiner = Joiner.allUntil(new CancelAfterTwoFailures<String>());
 751          * }
 752          *
 753          * <p> The following example uses {@code allUntil} to wait for all subtasks to
 754          * complete without any cancellation. This is similar to {@link #awaitAll()}
 755          * except that it yields a list of the completed subtasks.
 756          * {@snippet lang=java :
 757          *    <T> List<Subtask<T>> invokeAll(Collection<Callable<T>> tasks) throws InterruptedException {
 758          *        try (var scope = StructuredTaskScope.open(Joiner.<T>allUntil(_ -> false))) {
 759          *            tasks.forEach(scope::fork);
 760          *            return scope.join().toList();
 761          *        }
 762          *    }
 763          * }
 764          *
 765          * <p> The following example uses {@code allUntil} to get the results of all
 766          * subtasks that complete successfully within a timeout period.
 767          * {@snippet lang=java :
 768          *    <T> List<T> invokeAll(Collection<Callable<T>> tasks, Duration timeout) throws InterruptedException {
 769          *    try (var scope = StructuredTaskScope.open(Joiner.<T>allUntil(_ -> false), cf -> cf.withTimeout(timeout))) {
 770          *        tasks.forEach(scope::fork);
 771          *        return scope.join()
 772          *                 .filter(s -> s.state() == Subtask.State.SUCCESS)
 773          *                 .map(Subtask::get)
 774          *                 .toList();
 775          *         }
 776          *     }
 777          * }
 778          *
 779          * @param isDone the predicate to evaluate completed subtasks
 780          * @param <T> the result type of subtasks
 781          */
 782         static <T> Joiner<T, Stream<Subtask<T>>> allUntil(Predicate<Subtask<? extends T>> isDone) {
 783             return new Joiners.AllSubtasks<>(isDone);
 784         }
 785     }
 786 
 787     /**
 788      * Represents the configuration for a {@code StructuredTaskScope}.
 789      *
 790      * <p> The configuration for a {@code StructuredTaskScope} consists of a {@link
 791      * ThreadFactory} to create threads, an optional name for the purposes of monitoring
 792      * and management, and an optional timeout.
 793      *
 794      * <p> Creating a {@code StructuredTaskScope} with {@link #open()} or {@link #open(Joiner)}
 795      * uses the {@linkplain StructuredTaskScope##DefaultConfiguration default configuration}.
 796      * The default configuration consists of a thread factory that creates unnamed
 797      * {@linkplain Thread##virtual-threads virtual threads}, no name for monitoring and
 798      * management purposes, and no timeout.
 799      *
 800      * <p> Creating a {@code StructuredTaskScope} with its 2-arg {@link #open(Joiner, UnaryOperator)
 801      * open} method allows a different configuration to be used. The operator specified
 802      * to the {@code open} method is applied to the default configuration and returns the
 803      * configuration for the {@code StructuredTaskScope} under construction. The operator
 804      * can use the {@code with-} prefixed methods defined here to specify the components
 805      * of the configuration to use.
 806      *
 807      * <p> Unless otherwise specified, passing a {@code null} argument to a method
 808      * in this class will cause a {@link NullPointerException} to be thrown.
 809      *
 810      * @since 25
 811      */
 812     @PreviewFeature(feature = PreviewFeature.Feature.STRUCTURED_CONCURRENCY)
 813     sealed interface Configuration permits StructuredTaskScopeImpl.ConfigImpl {
 814         /**
 815          * {@return a new {@code Configuration} object with the given thread factory}
 816          * The other components are the same as this object. The thread factory is used by
 817          * a scope to create threads when {@linkplain #fork(Callable) forking} subtasks.
 818          * @param threadFactory the thread factory
 819          *
 820          * @apiNote The thread factory will typically create {@linkplain Thread##virtual-threads
 821          * virtual threads}, maybe with names for monitoring purposes, an {@linkplain
 822          * Thread.UncaughtExceptionHandler uncaught exception handler}, or other properties
 823          * configured.
 824          *
 825          * @see #fork(Callable)
 826          */
 827         Configuration withThreadFactory(ThreadFactory threadFactory);
 828 
 829         /**
 830          * {@return a new {@code Configuration} object with the given name}
 831          * The other components are the same as this object. A scope is optionally
 832          * named for the purposes of monitoring and management.
 833          * @param name the name
 834          */
 835         Configuration withName(String name);
 836 
 837         /**
 838          * {@return a new {@code Configuration} object with the given timeout}
 839          * The other components are the same as this object.
 840          * @param timeout the timeout
 841          *
 842          * @apiNote Applications using deadlines, expressed as an {@link java.time.Instant},
 843          * can use {@link Duration#between Duration.between(Instant.now(), deadline)} to
 844          * compute the timeout for this method.
 845          *
 846          * @see #join()
 847          * @see Joiner#onTimeout()
 848          */
 849         Configuration withTimeout(Duration timeout);
 850     }
 851 
 852     /**
 853      * Exception thrown by {@link #join()} when the outcome is an exception rather than a
 854      * result.
 855      *
 856      * @since 25
 857      */
 858     @PreviewFeature(feature = PreviewFeature.Feature.STRUCTURED_CONCURRENCY)
 859     final class FailedException extends RuntimeException {
 860         @java.io.Serial
 861         static final long serialVersionUID = -1533055100078459923L;
 862 
 863         /**
 864          * Constructs a {@code FailedException} with the specified cause.
 865          *
 866          * @param  cause the cause, can be {@code null}
 867          */
 868         FailedException(Throwable cause) {
 869             super(cause);
 870         }
 871     }
 872 
 873     /**
 874      * Exception thrown by {@link #join()} if the scope was opened with a timeout,
 875      * the timeout expired before or while waiting in {@code join}, and the {@link
 876      * Joiner#onTimeout() Joiner.onTimeout} method throws this exception.
 877      *
 878      * @since 25
 879      * @see Configuration#withTimeout(Duration)
 880      * @see Joiner#onTimeout()
 881      */
 882     @PreviewFeature(feature = PreviewFeature.Feature.STRUCTURED_CONCURRENCY)
 883     final class TimeoutException extends RuntimeException {
 884         @java.io.Serial
 885         static final long serialVersionUID = 705788143955048766L;
 886 
 887         /**
 888          * Constructs a {@code TimeoutException} with no detail message.
 889          */
 890         TimeoutException() { }
 891     }
 892 
 893     /**
 894      * Opens a new {@code StructuredTaskScope} to use the given {@code Joiner} object and
 895      * with configuration that is the result of applying the given operator to the
 896      * {@linkplain ##DefaultConfiguration default configuration}.
 897      *
 898      * <p> The {@code configOperator} is called with the default configuration and returns
 899      * the configuration for the new scope. The operator may, for example, set the
 900      * {@linkplain Configuration#withThreadFactory(ThreadFactory) ThreadFactory} or set a
 901      * {@linkplain Configuration#withTimeout(Duration) timeout}. If the operator completes
 902      * with an exception or error then it is propagated by this method. If the operator
 903      * returns {@code null} then {@code NullPointerException} is thrown.
 904      *
 905      * <p> If a {@code ThreadFactory} is set then its {@link ThreadFactory#newThread(Runnable)
 906      * newThread} method will be called to create threads when {@linkplain #fork(Callable)
 907      * forking} subtasks in this scope. If a {@code ThreadFactory} is not set then
 908      * forking subtasks will create an unnamed virtual thread for each subtask.
 909      *
 910      * <p> If a {@linkplain Configuration#withTimeout(Duration) timeout} is set then it
 911      * starts when the scope is opened. If the timeout expires before the scope has
 912      * {@linkplain #join() joined} then the scope is {@linkplain ##Cancallation cancelled}
 913      * and the {@code Joiner}'s {@link Joiner#onTimeout()} method is invoked to throw
 914      * optionally throw {@link TimeoutException TimeoutException}.
 915      *
 916      * <p> The new scope is owned by the current thread. Only code executing in this
 917      * thread can {@linkplain #fork(Callable) fork}, {@linkplain #join() join}, or
 918      * {@linkplain #close close} the scope.
 919      *
 920      * <p> Construction captures the current thread's {@linkplain ScopedValue scoped
 921      * value} bindings for inheritance by threads started in the scope.
 922      *
 923      * @param joiner the joiner
 924      * @param configOperator the operator to produce the configuration
 925      * @return a new scope
 926      * @param <T> the result type of subtasks executed in the scope
 927      * @param <R> the result type of the scope
 928      * @since 26
 929      */
 930     static <T, R> StructuredTaskScope<T, R> open(Joiner<? super T, ? extends R> joiner,
 931                                                  UnaryOperator<Configuration> configOperator) {
 932         return StructuredTaskScopeImpl.open(joiner, configOperator);
 933     }
 934 
 935     /**
 936      * Opens a new {@code StructuredTaskScope}to use the given {@code Joiner} object. The
 937      * scope is created with the {@linkplain ##DefaultConfiguration default configuration}.
 938      * The default configuration has a {@code ThreadFactory} that creates unnamed
 939      * {@linkplain Thread##irtual-threads virtual threads}, is unnamed for monitoring and
 940      * management purposes, and has no timeout.
 941      *
 942      * @implSpec
 943      * This factory method is equivalent to invoking the 2-arg open method with the given
 944      * joiner and the {@linkplain UnaryOperator#identity() identity operator}.
 945      *
 946      * @param joiner the joiner
 947      * @return a new scope
 948      * @param <T> the result type of subtasks executed in the scope
 949      * @param <R> the result type of the scope
 950      * @since 25
 951      */
 952     static <T, R> StructuredTaskScope<T, R> open(Joiner<? super T, ? extends R> joiner) {
 953         return open(joiner, UnaryOperator.identity());
 954     }
 955 
 956     /**
 957      * Opens a new {@code StructuredTaskScope} that can be used to fork subtasks that return
 958      * results of any type. The scope's {@link #join()} method waits for all subtasks to
 959      * succeed or any subtask to fail.
 960      *
 961      * <p> The {@code join} method returns {@code null} if all subtasks complete successfully.
 962      * It throws {@link FailedException} if any subtask fails, with the exception from
 963      * the first subtask to fail as the cause.
 964      *
 965      * <p> The scope is created with the {@linkplain ##DefaultConfiguration default
 966      * configuration}. The default configuration has a {@code ThreadFactory} that creates
 967      * unnamed {@linkplain Thread##virtual-threads virtual threads}, is unnamed for
 968      * monitoring and management purposes, and has no timeout.
 969      *
 970      * @implSpec
 971      * This factory method is equivalent to invoking the 2-arg open method with a joiner
 972      * created with {@link Joiner#awaitAllSuccessfulOrThrow() awaitAllSuccessfulOrThrow()}
 973      * and the {@linkplain UnaryOperator#identity() identity operator}.
 974      *
 975      * @param <T> the result type of subtasks
 976      * @return a new scope
 977      * @since 25
 978      */
 979     static <T> StructuredTaskScope<T, Void> open() {
 980         return open(Joiner.awaitAllSuccessfulOrThrow(), UnaryOperator.identity());
 981     }
 982 
 983     /**
 984      * Fork a subtask by starting a new thread in this scope to execute a value-returning
 985      * method. The new thread executes the subtask concurrently with the current thread.
 986      * The parameter to this method is a {@link Callable}, the new thread executes its
 987      * {@link Callable#call() call()} method.
 988      *
 989      * <p> This method first creates a {@link Subtask Subtask} object to represent the
 990      * <em>forked subtask</em>. It invokes the joiner's {@link Joiner#onFork(Subtask) onFork}
 991      * method with the subtask in the {@link Subtask.State#UNAVAILABLE UNAVAILABLE} state.
 992      * If the {@code onFork} completes with an exception or error then it is propagated by
 993      * the {@code fork} method without creating a thread. If the scope is already
 994      * {@linkplain ##Cancallation cancelled}, or {@code onFork} returns {@code true} to
 995      * cancel the scope, then this method returns the {@code Subtask}, in the
 996      * {@link Subtask.State#UNAVAILABLE UNAVAILABLE} state, without creating a thread to
 997      * execute the subtask.
 998      *
 999      * <p> If the scope is not cancelled, and the {@code onFork} method returns {@code false},
1000      * then a thread is created with the {@link ThreadFactory} configured when the scope
1001      * was opened, and the thread is started. Forking a subtask inherits the current thread's
1002      * {@linkplain ScopedValue scoped value} bindings. The bindings must match the bindings
1003      * captured when the scope was opened. If the subtask completes (successfully or with
1004      * an exception) before the scope is cancelled, then the thread invokes the joiner's
1005      * {@link Joiner#onComplete(Subtask) onComplete} method with the subtask in the
1006      * {@link Subtask.State#SUCCESS SUCCESS} or {@link Subtask.State#FAILED FAILED} state.
1007      * If the {@code onComplete} method completes with an exception or error, then the
1008      * {@linkplain Thread.UncaughtExceptionHandler uncaught exception handler} is invoked
1009      * with the exception or error before the thread terminates.
1010      *
1011      * <p> This method returns the {@link Subtask Subtask} object. In some usages, this
1012      * object may be used to get its result. In other cases it may be used for correlation
1013      * or be discarded. To ensure correct usage, the {@link Subtask#get() Subtask.get()}
1014      * method may only be called by the scope owner to get the result after it has
1015      * waited for subtasks to complete with the {@link #join() join} method and the subtask
1016      * completed successfully. Similarly, the {@link Subtask#exception() Subtask.exception()}
1017      * method may only be called by the scope owner after it has joined and the subtask
1018      * failed. If the scope was cancelled before the subtask was forked, or before it
1019      * completes, then neither method can be used to obtain the outcome.
1020      *
1021      * <p> This method may only be invoked by the scope owner.
1022      *
1023      * @param task the value-returning task for the thread to execute
1024      * @param <U> the result type
1025      * @return the subtask
1026      * @throws WrongThreadException if the current thread is not the scope owner
1027      * @throws IllegalStateException if the owner has already {@linkplain #join() joined}
1028      * or the scope is closed
1029      * @throws StructureViolationException if the current scoped value bindings are not
1030      * the same as when the scope was created
1031      * @throws RejectedExecutionException if the thread factory rejected creating a
1032      * thread to run the subtask
1033      */
1034     <U extends T> Subtask<U> fork(Callable<? extends U> task);
1035 
1036     /**
1037      * Fork a subtask by starting a new thread in this scope to execute a method that
1038      * does not return a result.
1039      *
1040      * <p> This method works exactly the same as {@link #fork(Callable)} except that the
1041      * parameter to this method is a {@link Runnable}, the new thread executes its
1042      * {@link Runnable#run() run} method, and {@link Subtask#get() Subtask.get()} returns
1043      * {@code null} if the subtask completes successfully.
1044      *
1045      * @param task the task for the thread to execute
1046      * @param <U> the result type
1047      * @return the subtask
1048      * @throws WrongThreadException if the current thread is not the scope owner
1049      * @throws IllegalStateException if the owner has already {@linkplain #join() joined}
1050      * or the scope is closed
1051      * @throws StructureViolationException if the current scoped value bindings are not
1052      * the same as when the scope was created
1053      * @throws RejectedExecutionException if the thread factory rejected creating a
1054      * thread to run the subtask
1055      * @since 25
1056      */
1057     <U extends T> Subtask<U> fork(Runnable task);
1058 
1059     /**
1060      * Returns the result, or throws, after waiting for all subtasks to complete or
1061      * the scope to be {@linkplain ##Cancallation cancelled}.
1062      *
1063      * <p> This method waits for all subtasks started in this scope to complete or the
1064      * scope to be cancelled. If a {@linkplain Configuration#withTimeout(Duration) timeout}
1065      * is configured, and the timeout expires before or while waiting, then the scope is
1066      * cancelled and the {@code Joiner}'s {@link Joiner#onTimeout() onTimeout} method is
1067      * invoked to optionally throw {@link TimeoutException TimeoutException}. If the
1068      * {@code onTimeout} method throws another exception or error then it is propagated
1069      * by this method. Once finished waiting, and {@code onTimeout} does not throw, the
1070      * {@code Joiner}'s {@link Joiner#result() result()} method is invoked to get the result
1071      * or throw an exception. If the {@code result()} method throws then this method throws
1072      * {@code FailedException} with the exception from the {@code Joiner} as the cause.
1073      *
1074      * <p> This method may only be invoked by the scope owner. Once the result or
1075      * exception outcome is obtained, this method may not be invoked again. The only
1076      * case where the method may be called again is where {@code InterruptedException}
1077      * is thrown while waiting.
1078      *
1079      * @return the result
1080      * @throws WrongThreadException if the current thread is not the scope owner
1081      * @throws IllegalStateException if already joined or this scope is closed
1082      * @throws FailedException if the <i>outcome</i> is an exception, thrown with the
1083      * exception from {@link Joiner#result() Joiner.result()} as the cause
1084      * @throws TimeoutException if a timeout is set, the timeout expires before or while
1085      * waiting, and {@link Joiner#onTimeout() Joiner.onTimeout()} throws this exception
1086      * @throws InterruptedException if interrupted while waiting
1087      * @since 25
1088      */
1089     R join() throws InterruptedException;
1090 
1091     /**
1092      * {@return {@code true} if this scope is {@linkplain ##Cancallation cancelled} or in
1093      * the process of being cancelled, otherwise {@code false}}
1094      *
1095      * <p> Cancelling the scope prevents new threads from starting in the scope and
1096      * {@linkplain Thread#interrupt() interrupts} threads executing unfinished subtasks.
1097      * It may take some time before the interrupted threads finish execution; this
1098      * method may return {@code true} before all threads have been interrupted or before
1099      * all threads have finished.
1100      *
1101      * @apiNote A task with a lengthy "forking phase" (the code that executes before
1102      * it invokes {@link #join() join}) may use this method to avoid doing work in cases
1103      * where scope is cancelled by the completion of a previously forked subtask or timeout.
1104      *
1105      * @since 25
1106      */
1107     boolean isCancelled();
1108 
1109     /**
1110      * Closes this scope.
1111      *
1112      * <p> This method first {@linkplain ##Cancallation cancels} the scope, if not
1113      * already cancelled. This interrupts the threads executing unfinished subtasks. This
1114      * method then waits for all threads to finish. If interrupted while waiting then it
1115      * will continue to wait until the threads finish, before completing with the interrupt
1116      * status set.
1117      *
1118      * <p> This method may only be invoked by the scope owner. If the scope
1119      * is already closed then the scope owner invoking this method has no effect.
1120      *
1121      * <p> A {@code StructuredTaskScope} is intended to be used in a <em>structured
1122      * manner</em>. If this method is called to close a scope before nested task
1123      * scopes are closed then it closes the underlying construct of each nested scope
1124      * (in the reverse order that they were created in), closes this scope, and then
1125      * throws {@link StructureViolationException}.
1126      * Similarly, if this method is called to close a scope while executing with
1127      * {@linkplain ScopedValue scoped value} bindings, and the scope was created
1128      * before the scoped values were bound, then {@code StructureViolationException} is
1129      * thrown after closing the scope.
1130      * If a thread terminates without first closing scopes that it owns then
1131      * termination will cause the underlying construct of each of its open tasks scopes to
1132      * be closed. Closing is performed in the reverse order that the scopes were
1133      * created in. Thread termination may therefore be delayed when the scope owner
1134      * has to wait for threads forked in these scopes to finish.
1135      *
1136      * @throws IllegalStateException thrown after closing the scope if the scope
1137      * owner did not attempt to join after forking
1138      * @throws WrongThreadException if the current thread is not the scope owner
1139      * @throws StructureViolationException if a structure violation was detected
1140      */
1141     @Override
1142     void close();
1143 }