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

Kam*_*l W 8 java asynchronous java-threads completable-future

有以下暂存代码:

  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();
  }
Run Code Online (Sandbox Code Playgroud)

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

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

syn*_*gma 11

如果您想避免返回CompletableFuture<Exception>并且能够首先抛出并且仍然能够执行某些操作,则会从所有CompletableFutures 收集异常。

在这种情况下,您可以使用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);
}
Run Code Online (Sandbox Code Playgroud)