如何使用多线程并使用completeFuture获取几个线程的返回值,并汇总
时间: 2025-04-02 19:17:47 AIGC 浏览: 73
在 Java 中,可以使用 `CompletableFuture` 类来简化多线程操作,并能够轻松获取多个线程的返回值并将它们汇总在一起。下面是一个详细的步骤说明以及示例代码。
---
### 步骤分析
1. **创建任务**:每个任务可以用 `Runnable` 或 `Callable` 表达,这里我们通常用 `Supplier<T>` 封装任务。
2. **并发执行**:利用 `CompletableFuture.supplyAsync()` 方法将任务提交给线程池异步执行。
3. **合并结果**:使用 `thenCombine` 或 `allOf` 方法将所有线程的结果组合起来。
4. **获取最终结果**:调用 `.join()` 或 `.get()` 获取汇总后的数据。
---
### 示例代码
假设我们需要计算三个数的平方并通过 `CompletableFuture` 合并结果:
```java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
// 计算某个数字的平方
private static int calculateSquare(int num) {
try {
Thread.sleep(100); // 模拟耗时运算
} catch (InterruptedException e) {
e.printStackTrace();
}
return num * num;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建三个 CompletableFutures 分别计算 2、3、5 的平方
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> calculateSquare(2));
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> calculateSquare(3));
CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> calculateSquare(5));
// 使用 allOf 来等待所有的 Future 执行完毕
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2, future3);
// 等待所有任务完成后再收集结果
combinedFuture.thenRun(() -> {
try {
int result = future1.get() + future2.get() + future3.get(); // 汇总结果
System.out.println("Total Sum of Squares: " + result);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
});
// 主线程睡眠以便观察子线程运行情况
Thread.sleep(500);
}
}
```
---
### 结果解释
上述代码会分别开启三个线程计算输入数值 (`2`, `3`, `5`) 的平方,然后将这些结果相加得到总数。
#### 输出样例:
```
Total Sum of Squares: 38
```
这是因为 `(2^2) + (3^2) + (5^2)` 等于 `4 + 9 + 25 = 38`.
---
### 注意事项
1. 默认情况下,`supplyAsync()` 使用的是公共的 ForkJoinPool 线程池。如果需要自定义线程池,可以通过第二个参数传入 `ExecutorService`。
```java
ExecutorService customThreadPool = Executors.newFixedThreadPool(10);
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> calculateSquare(2), customThreadPool);
```
2. 如果某些任务可能会抛出异常,则可以链式添加 `.exceptionally()` 方法来捕获异常并处理。
---
阅读全文
相关推荐



















