CountDownLatch翻车后,我建议用CompletableFuture改造下

Java8 CompletableFuture深度解析:异步编程与异常处理

CompletableFuture改造

我先直接分享一下我是如何使用CompletableFuture的吧

// 下载文件总数,初始化
List<Integer> resultList = new ArrayList<>(1000);
ConcurrentHashMap<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
IntStream.range(0,1000).forEach(resultList::add);

public List<R> sendAsyncBatch(List<P> list, Executor executor, TaskLoader<R,P> loader) {

    List<R> resultList = new CopyOnWriteArrayList<>();
    if (CollectionUtils.isNotEmpty(list)) {
        Executor finalExecutor = executor;
        // 将任务拆分分成每50个为一个任务
        CollUtil.split(list, 50)
                .forEach(tempList -> {
                    CompletableFuture[] completableFutures = tempList.stream()
                            .map(p -> CompletableFuture.supplyAsync(() -> {
                                try {
                                    return loader.load(p);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                return null;
                            }, finalExecutor)
                                    .handle((result, throwable) -> {
                                        if (Objects.nonNull(throwable)) {
                                            //log.error("async error:{}", throwable.getMessage());
                                        } else if (Objects.nonNull(result)) {
                                            //log.info("async success:{}", result);
                                        } else {
                                            //log.error("async result is null");
                                        }
                                        return result;
                                    }).whenComplete((r, ex) -> {
                                        if (Objects.nonNull(r)) {
                                            resultList.add((R) r);
                                        }
                                    })
                            ).toArray(CompletableFuture[]::new);
          
### CountDownLatch 结合 CompletableFuture 使用方法 在 Java 并发编程中,`CountDownLatch` `CompletableFuture` 可以很好地结合起来处理复杂的并发场景。下面是一个具体的例子说明如何将两者结合使用。 #### 示例代码 假设有一个任务需要多个子任务完成后才能继续执行后续逻辑: ```java import java.util.concurrent.*; public class LatchAndFutureExample { public static void main(String[] args) throws InterruptedException { // 定义计数器初始值为3,表示有三个子任务 CountDownLatch latch = new CountDownLatch(3); // 创建一个带有自定义线程工厂的线程池 ExecutorService executor = Executors.newFixedThreadPool(3); // 存储所有的 completable futures var allFutures = new ArrayList<CompletableFuture<Void>>(); try { for (int i = 0; i < 3; ++i) { final int taskId = i; // 对于每一个子任务都创建一个新的 CompletableFuture 实例 CompletableFuture<Void> futureTask = CompletableFuture.runAsync(() -> { System.out.println("Executing task " + taskId); // 模拟耗时操作 try { Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} // 当前子任务完成之后减少计数值 latch.countDown(); }, executor).thenRun(() -> { // 所有的 thenRun 都会在对应的 runAsync 完成后触发 System.out.println("Task " + taskId + " has finished."); }); // 添加到列表以便稍后统一处理结果 allFutures.add(futureTask); } // 主线程在此处等待直到所有子任务均已完成 latch.await(); // 统一处理各个 Future 的最终状态 CompletableFuture.allOf(allFutures.toArray(new CompletableFuture[0])).join(); System.out.println("All tasks have been completed."); } finally { executor.shutdown(); } } } ``` 此程序展示了如何利用 `CountDownLatch` 来同步一组并行运行的任务,并且通过 `CompletableFuture` 提供更强大的组合能力[^1]。 当涉及到更加复杂的应用场景时,比如某些情况下可能希望某个特定条件满足后再去启动其他依赖的操作,则可以考虑进一步探索 `CompletableFuture` 更多高级特性如 `completeOnTimeout`, `orTimeout` 等来增强灵活性响应速度[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值