关于CompletableFuture的一切,看这篇文章就够了
文章目录
- CompletableFuture作为Future使用
- 异步执行code
- 组合Futures
- thenApply() 和 thenCompose()的区别
- 并行执行任务
- 异常处理
java中CompletableFuture的使用
之前的文章中,我们讲解了Future, 本文我们将会继续讲解java 8中引入的CompletableFuture的用法。
CompletableFuture首先是一个Future,它拥有Future所有的功能,包括获取异步执行结果,取消正在执行的任务等。
除此之外,CompletableFuture还是一个CompletionStage。
我们看下CompletableFuture的定义:
public class CompletableFuture<T> implements Future<T>, CompletionStage<T>
什么是CompletionStage呢?
在异步程序中,如果将每次的异步执行都看成是一个stage的话,我们通常很难控制异步程序的执行顺序,在javascript中,我们需要在回调中执行回调。这就会形成传说中的回调地狱。
好在在ES6中引入了promise的概念,可以将回调中的回调转写为链式调用,从而大大的提升了程序的可读性和可写性。
同样的在java中,我们使用CompletionStage来实现异步调用的链式操作。
CompletionStage定义了一系列的then*** 操作来实现这一功能。
CompletableFuture作为Future使用
调用CompletableFuture.complete方法可以立马返回结果,我们看下怎么使用这个方法来构建一个基本的Future:
public Future<String> calculateAsync() throws InterruptedException {CompletableFuture<String> completableFuture= new CompletableFuture<>();Executors.newCachedThreadPool().submit(() -> {Thread.sleep(500);completableFuture.complete("Hello");return null;});return completableFuture;}
上面我们通过调动ExecutorService来提交一个任务从而得到一个Future。如果你知道执行的结果,那么可以使用CompletableFuture的completedFuture方法来直接返回一个Future。
public Future<String> useCompletableFuture(){Future<String> completableFuture =CompletableFuture.completedFuture("Hello");return completableFuture;}
CompletableFuture还提供了一个cancel方法来立马取消任务的执行:
public Future<String> calculateAsyncWithCancellation() throws InterruptedException {CompletableFuture<String> completableFuture = new CompletableFuture<>();Executors.newCachedThreadPool().submit(() -> {Thread.sleep(500);completableFuture.cancel(false);return null;});return completableFuture;}
如果这个时候调用Future的get方法,将会报CancellationException异常。
Future<String> future = calculateAsyncWithCancellation();
future.get(); // CancellationException
异步执行code
CompletableFuture提供了runAsync和supplyAsync的方法,可以以异步的方式执行代码。
我们看一个runAsync的基本应用,接收一个Runnable参数:
public void runAsync(){CompletableFuture<Void> runAsync= CompletableFuture.runAsync(()->{log.info("runAsync");});}
而supplyAsync接受一个Supplier:
public void supplyAsync(){CompletableFuture<String> supplyAsync=CompletableFuture.supplyAsync(()->{return "supplyAsync";});}
他们两个的区别是一个没有返回值,一个有返回值。
组合Futures
上面讲到CompletableFuture的一个重大作用就是将回调改为链式调用,从而将Futures组合起来。
而链式调用的返回值还是CompletableFuture,我们看一个thenCompose的例子:
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello").thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"));
thenCompose将前一个Future的返回结果作为后一个操作的输入。
如果我们想合并两个CompletableFuture的结果,则可以使用thenCombine:
public void thenCombine(){CompletableFuture<String> completableFuture= CompletableFuture.supplyAsync(() -> "Hello").thenCombine(CompletableFuture.supplyAsync(() -> " World"), (s1, s2) -> s1 + s2));}
如果你不想返回结果,则可以使用thenAcceptBoth:
public void thenAcceptBoth(){CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> "Hello").thenAcceptBoth(CompletableFuture.supplyAsync(() -> " World"),(s1, s2) -> System.out.println(s1 + s2));}
thenApply() 和 thenCompose()的区别
thenApply()和thenCompose()两个方法都可以将CompletableFuture连接起来,但是两个有点不一样。
thenApply()接收的是前一个调用返回的结果,然后对该结果进行处理。
thenCompose()接收的是前一个调用的stage,返回flat之后的的CompletableFuture。
简单点比较,两者就像是map和flatMap的区别。
并行执行任务
当我们需要并行执行任务时,通常我们需要等待所有的任务都执行完毕再去处理其他的任务,那么我们可以用到CompletableFuture.allOf方法:
public void allOf(){CompletableFuture<String> future1= CompletableFuture.supplyAsync(() -> "Hello");CompletableFuture<String> future2= CompletableFuture.supplyAsync(() -> "Beautiful");CompletableFuture<String> future3= CompletableFuture.supplyAsync(() -> "World");CompletableFuture<Void> combinedFuture= CompletableFuture.allOf(future1, future2, future3);}
allOf只保证task全都执行,而并没有返回值,如果希望带有返回值,我们可以使用join:
public void join(){CompletableFuture<String> future1= CompletableFuture.supplyAsync(() -> "Hello");CompletableFuture<String> future2= CompletableFuture.supplyAsync(() -> "Beautiful");CompletableFuture<String> future3= CompletableFuture.supplyAsync(() -> "World");String combined = Stream.of(future1, future2, future3).map(CompletableFuture::join).collect(Collectors.joining(" "));}
上面的程序将会返回:“Hello Beautiful World”。
异常处理
如果在链式调用的时候抛出异常,则可以在最后使用handle来接收:
public void handleError(){String name = null;CompletableFuture<String> completableFuture= CompletableFuture.supplyAsync(() -> {if (name == null) {throw new RuntimeException("Computation error!");}return "Hello, " + name;}).handle((s, t) -> s != null ? s : "Hello, Stranger!");}
这和Promise中的catch方法使用类似。
本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/CompletableFuture
更多精彩内容且看:
- 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
- Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
- Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
- java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程
更多教程请参考 flydean的博客
关于CompletableFuture的一切,看这篇文章就够了相关推荐
- Vue开发入门看这篇文章就够了
摘要: 很多值得了解的细节. 原文:Vue开发看这篇文章就够了 作者:Random Fundebug经授权转载,版权归原作者所有. 介绍 Vue 中文网 Vue github Vue.js 是一套构建 ...
- Android 8.0新特性(看这篇文章就够了)
2019独角兽企业重金招聘Python工程师标准>>> 在刚结束不久的谷歌 I/O2017开发者大会上发布的第二个Android O(安卓8.0)开发者预览,并且向普通用户开放了第二 ...
- 好多人都说存储过程很难?认真看这篇文章就够了
何为存储过程? 存储过程是在数据库管理系统中保存的.预先编译的并能实现某种功能的sql程序,说直白点,java知道吧?和java的方法一样. 每遇到一个新的知识点时,我们都会看看它的优点,从而加深对它 ...
- 使用分层网络模型的两个优点是什么_从零开始学网络|搞懂OSI参考模型和TCP/IP分层模型,看这篇文章就够了...
从零开始学网络|搞懂OSI参考模型和TCP/IP分层模型,看这篇文章就够了mp.weixin.qq.com 前言 今天和大家一起谈谈"网络",之前写的文章可能不太通俗易懂,有人就 ...
- python入门书籍推荐,看这篇文章就够,请!
python入门书籍推荐,看这篇文章就够,请! 事实上,有关python的书籍很多很多,就当当网就有50000件和python有关的书籍,我特地去了当地的新华书店,蹲了大半天,回来给大家推荐,适合想学 ...
- 万字心得,PMP学习考试那些事儿,看这篇文章就够了
声明:文章为原创,首发于知乎,链接:万字长文!PMP考试那些事儿,看这篇文章就够了 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/524966002 以下内 ...
- 斗鱼html5插件音画不同步,音画不同步在直播中怎么解决?看这篇文章就够了!...
原标题:音画不同步在直播中怎么解决?看这篇文章就够了! 什么是音画不同步? 很容易判断,就是画面和声音不匹配. 为什么会音画不同步? 首先我们要明白一个概念,虽然人的肉眼很容易辨别音画是否同步的,但是 ...
- java黄油刀_ButterKnife原理解析看这篇文章就够了
原标题:ButterKnife原理解析看这篇文章就够了 作者:SheHuan https://juejin.im/post/5acec2b46fb9a028c6761628 ButterKnife 算 ...
- Python-Excel 零基础学习xlwings,看这篇文章就够了
零基础学习xlwings,看这篇文章就够了 | 一起大数据-技术文章心得 (17bigdata.com) 1.xlwings是什么 2.xlwings安装更新与卸载 3.xlwings详细使用 4.案 ...
- 文科好应该学计算机哪类专业,文科理科分别适合哪些专业?看这篇文章就够了!...
原标题:文科理科分别适合哪些专业?看这篇文章就够了! 如何选择一个好的学校 心仪的专业 至关重要 你想好读什么专业了吗? 学计算机就要修电脑? 学机械就是混车间? 男生喜欢什么样的? 女生都报什么专业 ...
最新文章
- 五年级上册计算机课如何拉表格,川教版小学信息技术五年级上册第八课 调整表格...
- iOS单例模式定义与使用
- ubuntu更新rtl8192cu驱动
- Arduino--Mlx90614红外温度传感器(额温枪芯片)
- Boost:列出设备的测试程序
- 祝贺!王春雨入职一个月晋升副教授
- AngularJs-指令和指令之间的交互(动感超人)
- 关系模式候选键求取的算法
- 晨哥真有料丨盘点追女生的作死行为!
- eclipse新建maven报错
- 在spring boot中3分钟上手RPC框架Dubbo
- Linux系统下查看网卡的UUID
- 局域网ip扫描工具_Network Kit X for Mac(网络检测工具箱)
- 分享视频分析软件常用的几个C++库
- 区块链游戏的2018:曙光微现,路尚遥远
- 读取jpeg图像数据
- java加密文件夹_怎样用JAVA给文件夹加密,拜求各位大侠!
- 参加“灵狐公司”的技术年会,感受最新MS OFFICE 2007的应用价值!
- jenkins中的流水线( pipeline)的理解(未完)
- CAN休眠唤醒压力测试