7

Java 8's CompletableFuture.allOf(CompletableFuture<?>...cfs) will return a CompletableFuture that is completed when all the given futures complete, or throws a CompletionException if one of the futures completes with an exception.

If one of my futures completes with an exception, will CompletableFuture.allOf wait for the remaining futures to complete before throwing the CompletionException or will it cancel the remaining futures?

If it waits for all futures to complete, it there any way to make it return immediately when any future throws an exception and cancel the remaining futures?

abagshaw
  • 6,162
  • 4
  • 38
  • 76

1 Answers1

11

If one of my futures completes with an exception, will CompletableFuture.allOf wait for the remaining futures to complete before throwing the CompletionException

Yes, it will still wait for all the futures to complete.

You could use this helper method to create a CompletableFuture which completes exceptionally once any of the futures does so.

public static CompletableFuture allOfTerminateOnFailure(CompletableFuture<?>... futures) {
    CompletableFuture<?> failure = new CompletableFuture();
    for (CompletableFuture<?> f: futures) {
        f.exceptionally(ex -> {
            failure.completeExceptionally(ex);
            return null;
        });
    }
    return CompletableFuture.anyOf(failure, CompletableFuture.allOf(futures));
}

If you also want to cancel all other futures if one of them completes exceptionally, you could do it like this before returning from this method:

failure.exceptionally(ex -> {
    Arrays.stream(futures).forEach(f -> f.cancel(true));
    return null;
});
Kirill Simonov
  • 8,257
  • 3
  • 18
  • 42
  • Is it also possible to call `cancel(true)` on all of the futures inside `f.exceptionally()`? I would assume that it will also work, since we are saying that on an exception, we want all futures to cancel. But I guess this will result in redundant `cancel` calls? – mnestorov May 22 '20 at 08:50
  • 1
    @mnestorov yes, it's possible to call it from there, and you are right, it will result in extra `cancel` calls. – Kirill Simonov May 22 '20 at 15:11