CompletableFuture详解~allOf

CompletableFuture详解~allOf

当所有的阶段都完成后创建一个阶段

  • 上一个例子是当任意一个阶段完成后接着处理,接下来的两个例子演示当所有的阶段完成后才继续处理, 同步地方式和异步地方式两种。

  • static void allOfExample() {
        StringBuilder result = new StringBuilder();
        List messages = Arrays.asList("a", "b", "c");
        List<CompletableFuture> futures = messages.stream()
                .map(msg -> CompletableFuture.completedFuture(msg).thenApply(s -> delayedUpperCase(s)))
                .collect(Collectors.toList());
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).whenComplete((v, th) -> {
            futures.forEach(cf -> assertTrue(isUpperCase(cf.getNow(null))));
            result.append("done");
        });
        assertTrue("Result was empty", result.length() > 0);
    }
    

当所有的阶段都完成后异步地创建一个阶段

  • 使用thenApplyAsync()替换那些单个的CompletableFutures的方法,allOf()会在通用池中的线程中异步地执行。所以我们需要调用join方法等待它完成。

  • static void allOfAsyncExample() {
        StringBuilder result = new StringBuilder();
        List messages = Arrays.asList("a", "b", "c");
        List<CompletableFuture> futures = messages.stream()
                .map(msg -> CompletableFuture.completedFuture(msg).thenApplyAsync(s -> delayedUpperCase(s)))
                .collect(Collectors.toList());
        CompletableFuture allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]))
                .whenComplete((v, th) -> {
                    futures.forEach(cf -> assertTrue(isUpperCase(cf.getNow(null))));
                    result.append("done");
                });
        allOf.join();
        assertTrue("Result was empty", result.length() > 0);
    }
    

真实的例子

  • 现在你已经了解了CompletionStage 和 CompletableFuture 的一些函数的功能,下面的例子是一个实践场景:

  • 首先异步调用cars方法获得Car的列表,它返回CompletionStage场景。cars消费一个远程的REST API。

  • 然后我们复合一个CompletionStage填写每个汽车的评分,通过rating(manufacturerId)返回一个CompletionStage, 它会异步地获取汽车的评分(可能又是一个REST API调用)

  • 当所有的汽车填好评分后,我们结束这个列表,所以我们调用allOf得到最终的阶段, 它在前面阶段所有阶段完成后才完成。

  • 在最终的阶段调用whenComplete(),我们打印出每个汽车和它的评分。

  • cars().thenCompose(cars -> {
        List<CompletionStage> updatedCars = cars.stream()
                .map(car -> rating(car.manufacturerId).thenApply(r -> {
                    car.setRating(r);
                    return car;
                })).collect(Collectors.toList());
     
        CompletableFuture done = CompletableFuture
                .allOf(updatedCars.toArray(new CompletableFuture[updatedCars.size()]));
        return done.thenApply(v -> updatedCars.stream().map(CompletionStage::toCompletableFuture)
                .map(CompletableFuture::join).collect(Collectors.toList()));
    }).whenComplete((cars, th) -> {
        if (th == null) {
            cars.forEach(System.out::println);
        } else {
            throw new RuntimeException(th);
        }
    }).toCompletableFuture().join();
    
  • 因为每个汽车的实例都是独立的,得到每个汽车的评分都可以异步地执行,这会提高系统的性能(延迟),而且,等待所有的汽车评分被处理使用的是allOf方法,而不是手工的线程等待(Thread#join() 或 a CountDownLatch)。

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CompletableFutureJava8引入的一个异步编程工具类,用于简化异步编程,提高代码可读性和可维护性。它可以让你在一个线程中进行异步编程,而无需显式地创建线程或使用回调函数。 CompletableFuture可以看作是对Future的扩展,它支持链式调用和组合操作,可以将多个CompletableFuture组合在一起,形成一个复杂的异步操作流程。它也提供了一些方法,比如thenApply、thenAccept、thenRun等,用于处理异步操作的结果。 在使用CompletableFuture时,我们可以将异步操作放在一个CompletableFuture对象中,然后通过链式调用的方式,将多个异步操作组合在一起,形成一个异步操作流程。当所有的异步操作都执行完毕后,可以使用CompletableFuture的get方法,获取异步操作的结果。 下面是一个使用CompletableFuture的示例代码: ```java CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> { // 异步操作 return 10; }).thenApplyAsync(result -> { // 处理异步操作结果 return result * 2; }).thenApplyAsync(result -> { // 处理异步操作结果 return result + 3; }); // 获取异步操作的结果 Integer result = future.get(); ``` 在上面的代码中,我们首先使用CompletableFuture的supplyAsync方法,将异步操作放在一个CompletableFuture对象中。然后通过thenApplyAsync方法,将两个处理异步操作结果的函数串联在一起,形成一个异步操作流程。最后通过get方法,获取异步操作的结果。 除了thenApplyAsync方法,CompletableFuture还提供了许多其他的方法,比如thenAcceptAsync、thenRunAsync、thenComposeAsync等,可以根据具体需求来选择使用。 总之,CompletableFuture是一个非常强大的异步编程工具类,可以让你写出更加简洁、易读、易维护的异步代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jayues_lies

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值