CompleteFuture的用法,异步调用,等全部方法执行完获取返回值。

CompleteFuture的用法,异步调用,等全部方法执行完获取返回值。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

public class TestCompleteFuture {
    public static int i = 0;
    static CompletableFuture<String> findAccount(String accountId) {
        return CompletableFuture.supplyAsync(() -> {
            // mock finding account from database
            try {
                System.out.println(Thread.currentThread().getName()+":start!");
                Thread.sleep((++i)*1000);
                System.out.println(Thread.currentThread().getName()+":end!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "account" + accountId;
        });
    }

    public static void batchProcess(List<String> accountIdList) {
        // 并行根据accountId查找对应account
        List<CompletableFuture<String>> accountFindingFutureList =
                accountIdList.stream().map(accountId -> findAccount(accountId)).collect(Collectors.toList());

        // 使用allOf方法来表示所有的并行任务
        CompletableFuture<Void> allFutures =
                CompletableFuture
                        .allOf(accountFindingFutureList.toArray(new CompletableFuture[accountFindingFutureList.size()]));
        //allFutures.join();


        // 下面的方法可以帮助我们获得所有子任务的处理结果
        CompletableFuture<List<String>> finalResults = allFutures.thenApply(v -> accountFindingFutureList.stream().map(accountFindingFuture -> accountFindingFuture.join())
                .collect(Collectors.toList()));

        try {
            List<String> l = finalResults.get();
            System.out.println(l);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        List<String> l = new ArrayList<String >();
        l.add("11111");
        l.add("22222");
        l.add("33333");
        batchProcess(l);
    }
}

返回
在这里插入图片描述

在 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()` 方法来捕获异常并处理。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值