CompletableFuture 原理浅析

本文介绍了Java8中的CompletableFuture,它是并发编程的重要工具,支持异步计算和链式调用。通过示例代码和源码分析,阐述了CompletableFuture的执行流程,包括如何处理任务结果、何时执行回调,以及多个CompletableFuture之间的执行顺序。同时,文章通过图示帮助理解CompletableFuture的执行逻辑。
摘要由CSDN通过智能技术生成

 戳蓝字「TopCoder」关注我们哦!

Java8新增了CompletableFuture 提供对异步计算的支持,可以通过回调的方式处理计算结果,CompletableFuture 类实现了CompletionStageFuture接口,所以还可以像之前使用Future那样使用CompletableFuture ,尽管已不再推荐这样用了。

试想下这个场景:要执行一个任务逻辑(交给另一个线程处理),并针对任务结果转换,最后执行打印操作,那么该如完成呢?一种是使用Future.get获取任务结果并执行转换逻辑,最后执行打印操作,有没有像stream那样的处理方式呢?借助CompletableFuture的话,实现代码如下:

CompletableFuture.supplyAsync(() -> "000")
        .thenApply(s -> s.length()) // Function
        .whenComplete((integer, throwable) -> System.out.println(integer));

从上述的示例代码,我们可以大致分析下CompletableFuture的执行流程,首先CompletableFuture会异步执行supply任务,当supply任务执行结束时会自动执行对应的计算s.length()逻辑,这里问题来了?

当前调用thenApply方法的线程(这里是main线程)会对CompletableFuture提交Function(对应的是计算s.length()逻辑),那么到底是哪个线程执行的计算s.length()逻辑呢?由于supply任务是由其他线程来执行的(这里对应的是ForkJoin线程),当main线程调用thenApply方法时,不能确定supply任务是否执行完毕的!因此这时就要分2种情况:

  • 如果supply任务已经执行完毕,那么就需要当前main线程来执行s.length()逻辑;

  • 如果supply任务还未执行完毕,显然这时候main线程需要将Function记录到CompletableFuture中,这样当ForkJoin线程执行完supply任务时可以执行s.length()逻辑,这时就是 ForkJoin线程 来执行的。

对于上述的两种情况测试代码如下:

CompletableFuture.completedFuture("000")
        .thenApply(r -> r)
        .whenComplete((r, e) -> System.out.println(format(r)));

CompletableFuture.supplyAsync(() -> {
            LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));
            return "111";
        })
        .thenApply(r->r)
        .whenComplete((r, e) -> System.out.println(format(r))); 

private static String format(String msg) {
    return String.format
  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值