JUC篇——CompletableFuture实现异步编排,涵盖全部编排功能API,详细讲解异步编排实战场景,一篇文章彻底拿下!

为什么要使用CompletableFuture

CompletableFuture介绍:
CompletableFuture 是 Java 8 中新增的一个异步编程工具类,基于 Future 和 CompletionStage 接口构建。它支持 lambda,通过回调利用非阻塞方法,提升了异步编程模型。主要用于异步执行任务并返回结果,实现异步计算和操作组合。它提供了一种灵活、可组合的方式来实现异步计算,同时也提供了异常处理、取消、超时等特性。
在 CompletableFuture 中,我们可以通过回调函数来处理任务的结果,也可以使用其它方法来组合多个 CompletableFuture 对象,以构建更复杂的异步操作流水线。主要特性包括:
1、异步执行:CompletableFuture 可以在新的线程上异步执行计算或操作,从而不会阻塞主线程,提高程序的响应速度。
2、可组合性:CompletableFuture 的操作可以组合成一个或多个的 CompletableFuture 对象,从而构成复杂的异步计算链。
3、异常处理:CompletableFuture 可以对异常进行处理,通过 exceptionally() 方法可以捕获计算中的异常并返回默认值。
4、取消与超时:CompletableFuture 支持取消异步任务,还可以设置超时时间来避免任务的无限等待。
5、非阻塞式等待:CompletableFuture 提供了非阻塞式的等待方法,如 join() 和 getNow() 方法。
如何使用:
异步执行一个任务并获取结果:通过 CompletableFuture 的静态方法 supplyAsync() 可以异步执行一个任务,返回 CompletableFuture 对象,通过该对象可以获取任务执行的结果。
链式调用和结果聚合处理:在很多时候我们想链接多个 Future 来完成耗时较长的计算,此时需要合并结果并将结果发送到另一个任务中,该接口很难完成这种处理。而 CompletableFuture 解决了这一问题。

以上图为例,我们可以将你的多个好朋友看成是一个个的线程,有种可能是等他们都到了才开始点菜,还有就是来了一个人就开始点菜。视角转换到厨师的角度,厨师也可能会有多个人来处理你们的订单,炒你们下单的菜,那么厨师们可以上一个菜做完才能继续做下一个菜,或者这几个菜一起做,那么真实的案例应用到我们的开发当中,我们想实现这些线程的个性化调度,那么就得使用到JDK1.8的新特性中JUC下的CompletableFuture类来做处理

CompletableFuture的创建

1、简单的案例,调用他的runAsync方法,参数传递为下面的两个参数

演示案例:

控制台打印结果:

表示子线程成功执行了

2、调用supplyAsync方法,传递参数如下:

演示案例如下:

控制台:

CompletableFuture回调方法

CompletableFuture中的回调方法,在这里先介绍whenCompleteAsync方法,参数为下图

Biconsumer action参数中有两个参数,分别是上一个方法的返回值和抛出的异常

演示案例:
1、在任务1中调用whenCompleteAsync方法

2、在任务2中调用whenCompleteAsync方法

3、控制台:

分析控制台结果,因为任务1中的runAsync方法是没有返回值的,所以res是空的,但是任务2的方法supplyAsync是有返回值的,所以任务2中的res是上一个方法的返回值2

4、如果我在任务2中编写一段抛异常的代码,这个时候exec就会打印异常信息

控制台:

5、因为现在的这个方法是没有办法去处理抛出的异常的,所以有新的方法可以处理异常
这个方法的优势就是如果你监听的方法没有抛出异常,那么这个方法根本就不会执行

CompletableFuture串行方法

1、thenRun方法
这个方法没有入参也没有反参

演示实例:
因为本身runAsync方法就没有返回值,那么我们知识做了一个任务2必须要在任务1完成后再执行

控制台:

任务1执行完毕,睡眠1秒后任务2才开始执行

2、thenAccept方法
一般也是使用他的带线程池参数的重载方法,这个方法需要一个入参,但是没有返回值
注意,使用这个方法就不要用runAsync方法了,因为这个方法是没有返回值的,所以要用supplyAsync方法
演示实例:

控制台:
下面控制台的展示结果,还是会展示线程1和线程2的关系,线程1执行完毕休眠,线程2等待线程1执行完毕,所以在此同时,线程3开始执行,线程3睡眠过程中线程2在线程1执行完毕后执行了,所以我们看到了线程4的上面并不是线程3,而是线程2,我们还能看到线程4拿到了线程3的返回结果!

3、thehApply方法
一般也是使用重载方法,传线程池
该方法是传进一个参数,返回一个参数

演示实例:

控制台:
看到这个执行结果,发现线程1、3、5都是串行的执行,2、4、6线程会阻塞1秒等待。
我们看到线程6拿到了线程5的返回值,并且经过处理,返回了10000这条数据!

CompletableFuture两个任务都完成

1、两个任务完成后,再执行后面的业务
调用方法runAfterBothAsync,在Java中的实现方法如下:

2、两个任务执行完,拿到两个任务的返回值
调用thenAcceptBothAsync方法,传参数如下:

3、两个任务执行完,拿到两个任务的返回值,然后做完业务处理并有返回值
调用thenCombineAsync方法

CompletableFuture两个任务完成一个

1、两个任务完成任意1个后,执行后面的业务

控制台:
发现任务1完成直接执行了任务3,后面才执行的任务2

2、两个任务任意1个执行完,消费任务的返回值
注意,任务1和任务2的返回值必须要一致,可以写成返回值都为Object

3、两个任务任意一个执行完,消费任务的返回值,并有返回值

Completable多任务组合处理

1、场景:现在有多个任务,我希望等待这多个任务都执行完,再执行后面的业务逻辑。
CompletableFuture提供了静态方法,allOf,但是注意,如果真正想让后面的业务等待三个任务都执行完再执行,需要在allOf方法后调用get方法进行阻塞

控制台:
显而易见,最后的输出命令,是三个任务都执行完毕才执行的

2、场景:多个任务,如果有其中1个任务执行完毕,那么就直接执行后面的业务代码

至此,关于CompletableFuture实现异步编排的功能点介绍完毕,文章涉及知识点较多希望大家能收藏持续反复学习。后续还会持续更新相关技术点,敬请期待~~~

  • 28
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Be explorer

若认可笔者文章,手头富裕望支持

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

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

打赏作者

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

抵扣说明:

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

余额充值