/** * Returns a new CompletableFuture that is completed when all of * the given CompletableFutures complete. If any of the given * CompletableFutures complete exceptionally, then the returned * CompletableFuture also does so, with a CompletionException * holding this exception as its cause. Otherwise, the results, * if any, of the given CompletableFutures are not reflected in * the returned CompletableFuture, but may be obtained by * inspecting them individually. If no CompletableFutures are * provided, returns a CompletableFuture completed with the value * {@code null}. * *
Among the applications of this method is to await completion * of a set of independent CompletableFutures before continuing a * program, as in: {@code CompletableFuture.allOf(c1, c2, * c3).join();}. * * @param cfs the CompletableFutures * @return a new CompletableFuture that is completed when all of the * given CompletableFutures complete * @throws NullPointerException if the array or any of its elements are * {@code null} */ public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) { return andTree(cfs, 0, cfs.length - 1); }
这段代码定义了 CompletableFuture
类中的 allOf
静态方法。该方法的主要作用是:
CompletableFuture
对象作为参数CompletableFuture
对象,该对象在所有输入的 CompletableFuture
都完成时才会完成详细解释:
public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)
cfs
是一个可变参数,可以接收任意数量的 CompletableFuture
对象CompletableFuture
,表示不关心具体的返回值,只关心完成状态return andTree(cfs, 0, cfs.length - 1);
andTree
的私有方法,传入了 cfs
数组及其起始和结束索引andTree
方法可能使用了树形结构来组合多个 CompletableFuture
,以实现高效的并行处理CompletableFuture
异常完成,返回的 CompletableFuture
也会异常完成CompletionException
中如果没有提供任何 CompletableFuture
,返回一个已完成的 CompletableFuture
,其值为 null
CompletableFuture.allOf()
方法时,如果没有传入任何参数,即:CompletableFuture<Void> result = CompletableFuture.allOf();
CompletableFuture
对象:null
CompletableFuture
保持了方法的一致性CompletableFuture
调用 get()
或 join()
,它会立即返回,不会阻塞null
(因为 Void
类型在 Java 中只能是 null
)这种处理方式符合"空对象模式"的设计理念,避免了在没有任务时返回 null
或抛出异常,使得调用代码可以统一处理各种情况。
这个方法为并发编程提供了一种简洁有效的方式来协调多个异步操作的完成。
CompletableFuture.allOf 的最佳实践及示例如下:
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
// 模拟耗时操作
sleep(1000);
return "Result of Task 1";
});
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
sleep(2000);
return "Result of Task 2";
});
CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> {
sleep(3000);
return "Result of Task 3";
});
CompletableFuture.allOf(task1, task2, task3).join();
System.out.println(task1.get());
System.out.println(task2.get());
System.out.println(task3.get());
List<CompletableFuture<String>> futures = Arrays.asList(task1, task2, task3);
CompletableFuture<List<String>> allResults = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
List<String> results = allResults.get();
results.forEach(System.out::println);
这段代码展示了如何组合多个 CompletableFuture 的结果。让我们逐步解析:
List<CompletableFuture<String>> futures = Arrays.asList(task1, task2, task3);
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
futures.toArray(new CompletableFuture[0])
将 List 转换为数组CompletableFuture.allOf
创建一个新的 CompletableFuture,它会在所有输入的 CompletableFuture 完成时完成.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()))
thenApply
在 allOf 完成后执行v
是 void 类型,因为 allOf 返回 CompletableFutureCompletableFuture<List<String>> allResults = ...
List<String> results = allResults.get();
results.forEach(System.out::println);
关键点:
这种模式非常适合需要并行执行多个任务并收集所有结果的场景,既提高了效率,又保持了代码的简洁性。
CompletableFuture<String> failingTask = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Task failed");
});
CompletableFuture.allOf(task1, task2, failingTask)
.exceptionally(ex -> {
System.out.println("An error occurred: " + ex.getMessage());
return null;
})
.join();
这段代码展示了如何处理 CompletableFuture 中的异常。
创建一个会失败的任务:
CompletableFuture<String> failingTask = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Task failed");
});
CompletableFuture.supplyAsync
创建一个异步任务使用 CompletableFuture.allOf:
CompletableFuture.allOf(task1, task2, failingTask)
异常处理:
.exceptionally(ex -> {
System.out.println("An error occurred: " + ex.getMessage());
return null;
})
exceptionally
方法用于处理 CompletableFuture 链中的异常等待完成:
.join();
join()
方法等待 CompletableFuture 完成get()
类似,但不会抛出受检异常关键点:
exceptionally
方法只在发生异常时被调用exceptionally
,异常会在 join()
调用时抛出注意事项:
CompletableFuture.anyOf
配合自定义逻辑)这种异常处理方式使得 CompletableFuture 能够在复杂的异步场景中提供更强大和灵活的错误管理能力。
CompletableFuture<Void> allOf = CompletableFuture.allOf(task1, task2, task3);
try {
allOf.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("Operation timed out");
}
这段代码展示了如何为 CompletableFuture.allOf 设置超时。
创建组合任务:
CompletableFuture<Void> allOf = CompletableFuture.allOf(task1, task2, task3);
CompletableFuture.allOf
组合多个任务allOf
返回一个 CompletableFuture,它会在所有输入的 CompletableFuture 完成时完成设置超时并等待结果:
try {
allOf.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("Operation timed out");
}
get
方法的重载版本,它接受超时时间和时间单位allOf
的结果异常处理:
get
方法可能抛出其他异常:
关键点:
最佳实践:
示例扩展:
try {
allOf.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("Operation timed out");
// 取消所有任务
task1.cancel(true);
task2.cancel(true);
task3.cancel(true);
} catch (InterruptedException e) {
System.out.println("Operation was interrupted");
Thread.currentThread().interrupt(); // 重新设置中断状态
} catch (ExecutionException e) {
System.out.println("An error occurred during execution: " + e.getCause().getMessage());
}
这个扩展版本处理了所有可能的异常,并在超时时尝试取消任务。
使用超时机制可以增加程序的健壮性,特别是在处理网络请求或其他可能长时间运行的操作时。它允许你的程序在预定的时间内做出反应,而不是无限期地等待。
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(task1, task2, task3);
CompletableFuture<Void> allOf = CompletableFuture.allOf(task1, task2, task3);
CompletableFuture.allOf(anyOf, allOf)
.thenRun(() -> {
System.out.println("First completed: " + anyOf.join());
System.out.println("All completed");
})
.join();
这段代码展示了如何结合使用 CompletableFuture.anyOf
和 CompletableFuture.allOf
。
创建 anyOf 任务:
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(task1, task2, task3);
CompletableFuture.anyOf
返回一个新的 CompletableFuture,它会在任何一个输入的 CompletableFuture 完成时完成创建 allOf 任务:
CompletableFuture<Void> allOf = CompletableFuture.allOf(task1, task2, task3);
CompletableFuture.allOf
返回一个新的 CompletableFuture,它会在所有输入的 CompletableFuture 完成时完成组合 anyOf 和 allOf:
CompletableFuture.allOf(anyOf, allOf)
allOf
,但这次是等待 anyOf
和 allOf
都完成添加完成后的操作:
.thenRun(() -> {
System.out.println("First completed: " + anyOf.join());
System.out.println("All completed");
})
thenRun
添加一个在所有任务完成后执行的操作anyOf.join()
)等待完成:
.join();
join()
等待整个组合的 CompletableFuture 完成关键点:
anyOf
在任何一个任务完成时就会完成,而 allOf
要等所有任务都完成allOf
确保在打印结果时,所有操作都已完成join()
用于等待最终结果,它不会抛出受检异常使用场景:
注意事项:
anyOf.join()
可能会抛出未检查的异常,如果任何任务异常完成示例扩展:
CompletableFuture.allOf(anyOf, allOf)
.thenRun(() -> {
try {
System.out.println("First completed: " + anyOf.join());
System.out.println("All completed");
} catch (CompletionException e) {
System.out.println("An error occurred: " + e.getCause().getMessage());
}
})
.exceptionally(ex -> {
System.out.println("Unexpected error: " + ex.getMessage());
return null;
})
.join();
这个扩展版本增加了异常处理,使代码更加健壮。
这种组合使用 anyOf
和 allOf
的方式提供了强大的灵活性,允许你在复杂的异步场景中精确控制和监控任务的完成状态。
CompletableFuture.allOf
等待多个并行任务完成thenApply
或 thenAccept
处理所有任务的结果exceptionally
或 handle
处理可能发生的异常allOf
与其他 CompletableFuture 方法结合使用这些示例展示了 CompletableFuture.allOf
的多种用法,涵盖了常见的并发编程场景。根据具体需求,你可以选择合适的模式并进行适当的调整。