Interface StructuredTaskScope.Joiner<T,R>

Type Parameters:
T - the result type of subtasks executed in the scope
R - the result type of the scope
Enclosing interface:
StructuredTaskScopePREVIEW<T,R>
Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public static interface StructuredTaskScope.Joiner<T,R>
Joiner is a preview API of the Java platform.
Programs can only use Joiner when preview features are enabled.
Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.
An object used with a StructuredTaskScopePREVIEW to handle subtask completion and produce the result for the scope owner waiting in the joinPREVIEW method for subtasks to complete.

Joiner defines static methods to create Joiner objects for common cases:

  • allSuccessfulOrThrow() creates a Joiner that yields a stream of the completed subtasks for join to return when all subtasks complete successfully. It cancels the scope and causes join to throw if any subtask fails.
  • anySuccessfulResultOrThrow() creates a Joiner that yields the result of the first subtask to succeed for join to return. It causes join to throw if all subtasks fail.
  • awaitAllSuccessfulOrThrow() creates a Joiner that waits for all successful subtasks. It cancels the scope and causes join to throw if any subtask fails.
  • awaitAll() creates a Joiner that waits for all subtasks. It does not cancel the scope or cause join to throw.

In addition to the methods to create Joiner objects for common cases, the allUntil(Predicate) method is defined to create a Joiner that yields a stream of all subtasks. It is created with a Predicate that determines if the scope should continue or be cancelled. This Joiner can be built upon to create custom policies that cancel the scope based on some condition.

More advanced policies can be developed by implementing the Joiner interface. The onFork(Subtask) method is invoked when subtasks are forked. The onComplete(Subtask) method is invoked when subtasks complete with a result or exception. These methods return a boolean to indicate if scope should be cancelled. These methods can be used to collect subtasks, results, or exceptions, and control when to cancel the scope. The result() method must be implemented to produce the result (or exception) for the join method.

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

Since:
25
See Also:
  • Method Details

    • onFork

      default boolean onFork(StructuredTaskScope.SubtaskPREVIEW<? extends T> subtask)
      Invoked by fork(Callable)PREVIEW and fork(Runnable)PREVIEW when forking a subtask. The method is invoked from the task owner thread. The method is invoked before a thread is created to run the subtask.
      Parameters:
      subtask - the subtask
      Returns:
      true to cancel the scope, otherwise false
    • onComplete

      default boolean onComplete(StructuredTaskScope.SubtaskPREVIEW<? extends T> subtask)
      Invoked by the thread started to execute a subtask after the subtask completes successfully or fails with an exception. This method is not invoked if a subtask completes after the scope is cancelled.
      Parameters:
      subtask - the subtask
      Returns:
      true to cancel the scope, otherwise false
    • result

      R result() throws Throwable
      Invoked by the join()PREVIEW method to produce the result (or exception) after waiting for all subtasks to complete or the scope cancelled. The result from this method is returned by the join method. If this method throws, then join throws StructuredTaskScope.FailedExceptionPREVIEW with the exception thrown by this method as the cause.

      In normal usage, this method will be called at most once by the join method to produce the result (or exception). The behavior of this method when invoked directly, and invoked more than once, is undefined. Where possible, an implementation should return an equal result (or throw the same exception) on second or subsequent calls to produce the outcome.

      Returns:
      the result
      Throws:
      Throwable - the exception
    • allSuccessfulOrThrow

      Returns a new Joiner object that yields a stream of all subtasks when all subtasks complete successfully. The Joiner cancels the scope and causes join to throw if any subtask fails.

      If all subtasks complete successfully, the joiner's result() method returns a stream of all subtasks in the order that they were forked. If any subtask failed then the result method throws the exception from the first subtask to fail.

      Type Parameters:
      T - the result type of subtasks
      Returns:
      a new Joiner object that yields a stream of all subtasks when all subtasks complete successfully
    • anySuccessfulResultOrThrow

      static <T> StructuredTaskScope.JoinerPREVIEW<T,T> anySuccessfulResultOrThrow()
      Returns a new Joiner object that yields the result of any subtask that completed successfully. The Joiner causes join to throw if all subtasks fail.

      The joiner's result() method returns the result of a subtask that completed successfully. If all subtasks fail then the result method throws the exception from one of the failed subtasks. The result method throws NoSuchElementException if no subtasks were forked.

      Type Parameters:
      T - the result type of subtasks
      Returns:
      a new Joiner object that yields the result of any subtask that completed successfully
    • awaitAllSuccessfulOrThrow

      static <T> StructuredTaskScope.JoinerPREVIEW<T,Void> awaitAllSuccessfulOrThrow()
      Returns a new Joiner object that waits for subtasks to complete successfully. The Joiner cancels the scope and causes join to throw if any subtask fails.

      The joiner's result method returns null if all subtasks complete successfully, or throws the exception from the first subtask to fail.

      Type Parameters:
      T - the result type of subtasks
      Returns:
      a new Joiner object that waits for subtasks to complete successfully
    • awaitAll

      static <T> StructuredTaskScope.JoinerPREVIEW<T,Void> awaitAll()
      Returns a new Joiner object that waits for all subtasks to complete. The Joiner does not cancel the scope if a subtask fails.

      The joiner's result method returns null.

      Type Parameters:
      T - the result type of subtasks
      Returns:
      a new Joiner object that waits for all subtasks to complete
    • allUntil

      Returns a new Joiner object that yields a stream of all subtasks when all subtasks complete or a predicate returns true to cancel the scope.

      The joiner's onComplete(Subtask) method invokes the predicate's test method with the subtask that completed successfully or failed with an exception. If the test method returns true then the scope is cancelled. The test method must be thread safe as it may be invoked concurrently from several threads. If the test method completes with an exception or error, then the thread that executed the subtask invokes the uncaught exception handler with the exception or error before the thread terminates.

      The joiner's result() method returns the stream of all subtasks, in fork order. The stream may contain subtasks that have completed (in SUCCESSPREVIEW or FAILEDPREVIEW state) or subtasks in the UNAVAILABLEPREVIEW state if the scope was cancelled before all subtasks were forked or completed.

      The following example uses this method to create a Joiner that cancels the scope when two or more subtasks fail.

         class CancelAfterTwoFailures<T> implements Predicate<Subtask<? extends T>> {
              private final AtomicInteger failedCount = new AtomicInteger();
              @Override
              public boolean test(Subtask<? extends T> subtask) {
                  return subtask.state() == Subtask.State.FAILED
                          && failedCount.incrementAndGet() >= 2;
              }
          }
      
          var joiner = Joiner.all(new CancelAfterTwoFailures<String>());
      

      The following example uses allUntil to wait for all subtasks to complete without any cancellation. This is similar to awaitAll() except that it yields a stream of the completed subtasks.

         <T> List<Subtask<T>> invokeAll(Collection<Callable<T>> tasks) throws InterruptedException {
             try (var scope = StructuredTaskScope.open(Joiner.<T>allUntil(_ -> false))) {
                 tasks.forEach(scope::fork);
                 return scope.join().toList();
             }
         }
      
      Type Parameters:
      T - the result type of subtasks
      Parameters:
      isDone - the predicate to evaluate completed subtasks
      Returns:
      a new Joiner object that yields a stream of all subtasks when all subtasks complete or a predicate returns true to cancel the scope