那一般情况下,CompletableFuture allof 等待返回结果是使用get 还是join方法比较好?
时间: 2023-06-09 11:08:10 浏览: 350
通常情况下,使用CompletableFuture的get方法来等待所有的CompletableFuture对象返回结果是比较好的。get方法会等待所有的CompletableFuture对象都执行完毕,并且获取它们的返回值,然后将它们的返回值组成一个List返回。使用join方法也可以等待所有的CompletableFuture对象执行完毕,但是如果其中有一个CompletableFuture对象发生异常,它会直接抛出一个CompletionException。因此,get方法更加适合在等待CompletableFuture对象返回结果时进行异常处理。
相关问题
CompletableFuture 子线程出现问题会导致 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); 无限等待吗?如何避免这种情况发生
`CompletableFuture.allOf()` 方法用于等待一组 `CompletableFuture` 完成,如果其中任何一个任务抛出异常,整个操作会立即失败并返回那个异常。当传入的 `futures` 集合有一个或多个完成任务抛出了错误,`allOf().join()` 将会阻塞,直到这个错误被注意到。
如果你的一个子线程抛出未检查异常 (如 `InterruptedException`, `ExecutionException` 的子类),这可能会导致 `allOf().join()` 永远等待,因为你默认地捕获了所有 `Future` 中可能出现的异常,并且 `CompletableFuture` 并不会自动将中断传递给主线程。
为了避免这种情况,你可以:
1. **处理中断**:在使用 `.join()` 或其他同步操作之前,确保捕获并处理 `InterruptedException`,例如添加 `Thread.currentThread().interrupt()` 到可能发生中断的地方,然后在 `catch` 块里检查 `InterruptedException`。
```java
CompletableFuture.allOf(futures.toArray(new CompletableFuture))
.whenComplete((result, exc) -> {
if (exc instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
})
.join();
```
2. **只阻塞特定异常**:如果你只想等待那些成功的未来,可以使用 `.exceptionally()` 方法捕获异常,或者使用 `.thenApplyVoid(null)` 来忽略结果,只关注完成情况。
3. **使用 try-with-resources** 或者显式关闭 `Futures`:确保每个 `CompletableFuture` 在不再需要时被正确地取消或关闭,以防止意外的长时间等待。
```java
try (var future = ...; var anotherFuture = ...) {
CompletableFuture.allOf(future, anotherFuture)
.whenComplete((result, exc) -> handleCompletion(exc))
.get();
}
```
4. **使用 `.get(long timeout, TimeUnit unit)`**:设置一个超时时间,这样如果在未来一定时间内没有完成,会抛出 `TimeoutException` 而不是无限等待。
记住,在实际应用中,最好设计程序能够优雅地处理异步任务可能出现的问题,而不是简单依赖于无限等待。
CompletableFuture.allOf(
CompletableFuture.allOf() 方法是一个静态方法,它接受一个 CompletableFuture 数组作为参数,并返回一个新的 CompletableFuture,该 CompletableFuture 在所有输入 CompletableFuture 完成后完成。这个方法通常用于等待多个异步任务全部完成后再执行下一步操作。
例如,以下代码创建了两个 CompletableFuture 对象,然后使用 allOf() 方法等待它们都完成后输出结果:
```
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);
allFutures.join();
System.out.println(future1.get() + " " + future2.get());
```
输出结果为:Hello World。
阅读全文