从 CompletableFuture.allOf() 执行中收集抛出的异常

Collect thrown exceptions from CompletableFuture.allOf() execution

具有以下刮擦代码:

  public static void main(String[] args) throws ExecutionException, InterruptedException {

    CompletableFuture<Void> process1 = CompletableFuture.runAsync(() -> {
      System.out.println("Process 1 with exception");
      throw new RuntimeException("Exception 1");
    });

    CompletableFuture<Void> process2 = CompletableFuture.runAsync(() -> {
      System.out.println("Process 2 without exception");
    });

    CompletableFuture<Void> process3 = CompletableFuture.runAsync(() -> {
      System.out.println("Process 3 with exception");
      throw new RuntimeException("Exception 3");
    });

    CompletableFuture<Void> allOfProcesses = CompletableFuture.allOf(process1, process2, process3);

    allOfProcesses.get();
  }

我正在寻找如何收集 CompletableFuture.allOf() 中并行执行期间抛出的所有异常并将其映射到列表的方法。

我知道我可以通过返回异常 (CompletableFuture<Exception>) 而不是使用 CompletableFuture::join 抛出并收集它来做到这一点,但我认为抛出异常的方法比稍后返回并抛出更好

如果你想避免返回 CompletableFuture<Exception> 并且只是能够先抛出并且仍然能够做一些事情将从所有 CompletableFuture 中收集异常。

在这种情况下,您可以使用 CompletableFuture::exceptionally 来收集异常:

private static List<Throwable> collectedExceptions = Collections.synchronizedList(new ArrayList<>());

public static void main(String[] args) throws ExecutionException, InterruptedException {

    CompletableFuture<Void> process1 = CompletableFuture.runAsync(() -> {
        System.out.println("Process 1 with exception");
        throw new RuntimeException("Exception 1");
    }).exceptionally(exception -> {
        // Handle your exception here
        collectedExceptions.add(exception);
        return null;
    });

    CompletableFuture<Void> process2 = CompletableFuture.runAsync(() -> {
        System.out.println("Process 2 without exception");
    });

    CompletableFuture<Void> process3 = CompletableFuture.runAsync(() -> {
        System.out.println("Process 3 with exception");
        throw new RuntimeException("Exception 3");
    }).exceptionally(exception -> {
        // Handle your exception here
        collectedExceptions.add(exception);
        return null;
    });

    CompletableFuture<Void> allOfProcesses = CompletableFuture.allOf(process1, process2, process3);

    allOfProcesses.get();
    assert (collectedExceptions.size() == 2);
}