阿昌总结今天学习到的CompletableFuture
当我们在异步任务编程的时候,可能会有场景如下:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1LdHaaAS-1634223766164)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014221550374.png)]](https://img-blog.csdnimg.cn/4826ea8494234ab99682e7ef22c274d0.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_18,color_FFFFFF,t_70,g_se,x_16)
可能你会想到用之前我们学到的Callable的方式去获取结果后,再执行;
但是这样子不能保证是异步与异步之间的结果;
C不能感知到AB的结果后再异步执行;
所以,这里我们就引出了 ==CompletableFuture==
一、前言
什么是CompletableFuture呢?
CompletableFuture 和 FutureTask 同属于 Future 接口的实现类,都可以获取线程的执行结果。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nvaoL5aY-1634223766166)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014221836628.png)]](https://img-blog.csdnimg.cn/a1435bb71da5499f80a1d14574825b6d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_18,color_FFFFFF,t_70,g_se,x_16)
二、API
方法不以 Async 结尾,意味着 Action 使用相同的线程执行,而 Async 可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)
1、是否有返回值
()->{}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYXjP8gp-1634223766168)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014222101147.png)]](https://img-blog.csdnimg.cn/f4c64d4e9d99467eb9d8200e1a0e6823.png)
1 | CompletableFuture future = CompletableFuture.XXXAsync(()->{}); |
runXxxx都是没有返回结果的supplyXxx都是可以获取返回结果的可以传入
自定义的线程池,否则就用默认的线程池;
2、是否有回调方法,不能改变返回值
(t,error)->{}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gaYsfAPn-1634223766170)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014222323835.png)]](https://img-blog.csdnimg.cn/fe15a8958ad845a0b8da150fae6746fd.png)
只能返回结果,不能改变返回值
whenComplete 可以处理正常和异常的计算结果,exceptionally 处理异常情况。
- whenComplete 和 whenCompleteAsync 的区别:
- whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。
- whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池
来进行执行。
3、有回调方法,能改变返回值
(t,error)->{return xx;}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-428fVOoD-1634223766173)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014222901876.png)]](https://img-blog.csdnimg.cn/671dc1f4a1774eb3b678b206138e2e8d.png)
只能返回结果,能改变返回值
和 complete 一样,可对结果做最后的处理(可处理异常),可改变返回值。
4、线程串行化方法
T:上一个任务返回结果的类型
U:当前任务的返回值类型
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qlkCCQCb-1634223766175)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014223120068.png)]](https://img-blog.csdnimg.cn/a4b7d25a57c64b97aadee9cbc51fac5c.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_19,color_FFFFFF,t_70,g_se,x_16)
- **thenApply(
resp->{return xx;})**:- 当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值。
- **thenAccept(
resp->{})**:- 消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
- **thenRun(
()->{})**:- 只要上面的任务执行完成,就开始执行 thenRun,只是处理完任务后,执行thenRun 的后续操作
带有 Async 默认是异步执行的。同之前。
- 以上都要前置任务成功完成。
5、两任务组合—都要完成
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t3HmgRoQ-1634223766177)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014224101520.png)]](https://img-blog.csdnimg.cn/d2bc838a375a40bd9360bb4aab6e3c69.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_19,color_FFFFFF,t_70,g_se,x_16)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VejFV16m-1634223766179)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014224107385.png)]](https://img-blog.csdnimg.cn/eda5fbc48c6342a2878810c90dc07293.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_19,color_FFFFFF,t_70,g_se,x_16)
两个任务必须都完成,触发该任务。
下面的CompletableFuture为另一个任务
**thenCombine(
CompletableFuture,(r1,r2)->{return xx;},线程池)**:- 组合两个 future,获取两个 future 的返回结果,并返回当前任务的返回值
1
future01.thenCombineAsync(future02,(r1,r2)-{return xx;},excutor);
**thenAcceptBoth(
CompletableFuture,(r1,r2)->{},线程池)**:- 组合两个 future,获取两个 future 任务的返回结果,然后处理任务,没有返回值。
1
future01.thenAcceptBothAsync(future02,(f1,f2)->{},executor);
**runAfterBoth(
CompletableFuture,()->{},线程池)**:- 组合两个 future,不需要获取 future 的结果,只需两个 future 处理完任务后,处理该任务。
1
future01.runAfterBothAsync(future02,()->{},executor);
6、两任务组合 - - 一个完成
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8GzY58ZY-1634223766181)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014224726858.png)]](https://img-blog.csdnimg.cn/48054735d82c4fe89df35b681becff2f.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_20,color_FFFFFF,t_70,g_se,x_16)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HdzZQMq4-1634223766182)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014224733317.png)]](https://img-blog.csdnimg.cn/d4eff4fa4422472b81208e939da0cf9d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_19,color_FFFFFF,t_70,g_se,x_16)
当两个任务中,任意一个 future 任务完成的时候,执行任务。
下面的CompletableFuture为另一个任务
**applyToEither(
CompletableFuture,res->{return xxx;},线程池)**:- 两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值。
1
future01.applyToEitherAsync(future02,res->{},executor);
**acceptEither(
CompletableFuture,res->{},线程池)**:res为两个任务中执行完成的那个的返回值- 两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值。
1
future01.acceptEitherAsync(future02,res->{},executor);
**runAfterEither(
CompletableFuture,()->{},线程池)**:- 两个任务有一个执行完成,不需要获取 future 的结果,处理任务,也没有返回值。
1
future01.runAfterEitherAsync(future02,()->{},executor);
7、 多任务组合
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o7bjfkEk-1634223766184)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014225313597.png)]](https://img-blog.csdnimg.cn/92d561b587174694870567251b33aa82.png)
allOf:
- 等待所有任务完成
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PJvp4p74-1634223766185)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014225355717.png)]](https://img-blog.csdnimg.cn/33a8ed9798734f24a6823072ac0fe494.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zi_5piM5Zac5qyi5ZCD6buE5qGD,size_17,color_FFFFFF,t_70,g_se,x_16)
anyOf:
- 只要有一个任务完成
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BmjTBpfK-1634223766186)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20211014225419071.png)]](https://img-blog.csdnimg.cn/98f6811d3a214b92b07026080e33fc33.png)