那一般情况下,CompletableFuture allof 等待返回结果是使用get 还是join方法比较好?
时间: 2023-06-09 11:08:10 浏览: 408
通常情况下,使用CompletableFuture的get方法来等待所有的CompletableFuture对象返回结果是比较好的。get方法会等待所有的CompletableFuture对象都执行完毕,并且获取它们的返回值,然后将它们的返回值组成一个List返回。使用join方法也可以等待所有的CompletableFuture对象执行完毕,但是如果其中有一个CompletableFuture对象发生异常,它会直接抛出一个CompletionException。因此,get方法更加适合在等待CompletableFuture对象返回结果时进行异常处理。
相关问题
CompletableFuture allOf 方法
### Java `CompletableFuture.allOf` 方法详解
#### 1. 基本概念
`CompletableFuture.allOf` 是用于组合多个 `CompletableFuture` 实例的方法。该方法接收可变数量的 `CompletableFuture<?>... cfs` 参数并返回一个新的 `CompletableFuture<Void>`,当所有给定的 completable futures 都完成时它才会完成[^2]。
#### 2. 使用场景
此功能非常适合处理需要等待一组并发操作全部完成后才能继续的情况。通过这种方式可以有效地管理多个异步任务,并确保只有在所有任务都成功结束后才进行下一步逻辑。
#### 3. 示例代码
下面是一个简单的例子来展示如何使用 `allOf`:
```java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 定义三个不同的异步任务
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
return "Task 1";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(2000); } catch (InterruptedException e) {}
return "Task 2";
});
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(3000); } catch (InterruptedException e) {}
return "Task 3";
});
// 组合这些future对象到一个单一的任务中去
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2, future3);
// 等待所有的任务完成
combinedFuture.join();
// 获取各个任务的结果
System.out.println(future1.get());
System.out.println(future2.get());
System.out.println(future3.get());
// 输出总耗时
long startTime = System.currentTimeMillis();
combinedFuture.join(); // 这里再次调用join()只是为了演示目的,在实际应用中通常不需要这样做。
long endTime = System.currentTimeMillis();
System.out.printf("Total time taken: %d ms\n", (endTime - startTime));
}
}
```
在这个例子中,定义了三个不同延迟时间的任务,并利用 `CompletableFuture.allOf()` 将它们组合起来。程序会一直等到这三个任务都完成了之后再打印各自的结果以及整个过程所花费的时间。注意这里为了简化说明,直接用了 `Thread.sleep()` 来模拟长时间运行的操作;而在真实的应用环境中应当替换为具体的业务逻辑实现。
CompletableFuture 的 allOf 方法
### CompletableFuture.allOf 方法详解
#### 方法签名与返回值
`CompletableFuture.allOf(CompletableFuture<?>... cfs)` 接受可变数量的 `CompletableFuture` 对象作为参数,并返回一个新的 `CompletableFuture<Void>` 实例。此实例会在所有给定的 `CompletableFuture` 完成后完成。
#### 行为解释
一旦调用了 `allOf()` 并传入若干个 `CompletableFuture`,它会创建一个新的 `CompletableFuture<Void>` 来表示这些输入 completable futures 的组合状态。只有当所有的输入 completable futures 都已完成(无论是正常完成还是异常终止),由 `allOf()` 返回的那个 completable future 才会被标记为完成[^1]。
需要注意的是,即使其中一个或多个 completable futures 抛出了未捕获的异常,只要其他 completable futures 继续执行直到结束,则整个集合仍然被认为完成了;但是,在这种情况下尝试访问结果可能会触发异常传播。
#### 使用示例
下面是一个简单的例子来展示如何使用 `CompletableFuture.allOf`:
```java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class AllOfExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建三个异步任务
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "Task 1");
CompletableFuture<Integer> task2 = CompletableFuture.supplyAsync(() -> 42);
CompletableFuture<Double> task3 = CompletableFuture.supplyAsync(() -> Math.random());
// 将它们放入 allOf 中
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(task1, task2, task3);
// 等待所有任务完成
combinedFuture.join();
// 获取各个任务的结果
String result1 = task1.get();
Integer result2 = task2.get();
Double result3 = task3.get();
System.out.printf("Results are %s, %d and %.2f%n", result1, result2, result3);
}
}
```
在这个例子中,程序通过 `supplyAsync` 启动了三个不同的异步计算任务,并利用 `allOf` 方法确保这三个任务都完成后才继续向下执行。最后分别从各自的 completable futures 取得具体的结果并打印出来[^2]。
阅读全文