你有一个思想,我有一个思想,我们交换后,一个人就有两个思想
If you can NOT explain it simply, you do NOT understand it well enough
现陆续将Demo代码和技术文章整理在一起 Github实践精选 ,方便大家阅读查看,本文同样收录在此,觉得不错,还请Star🌟
前言
上一篇文章 不会用Java Future,我怀疑你泡茶没我快 全面分析了 Future,通过它我们可以获取线程的执行结果,它虽然解决了 Runnable 的 “三无” 短板,但是它自身还是有短板:
不能手动完成计算
假设你使用 Future 运行子线程调用远程 API 来获取某款产品的最新价格,服务器由于洪灾宕机了,此时如果你想手动结束计算,而是想返回上次缓存中的价格,这是 Future 做不到的
调用 get() 方法会阻塞程序
Future 不会通知你它的完成,它提供了一个get()方法,程序调用该方法会阻塞直到结果可用为止,没有办法利用回调函数附加到Future,并在Future的结果可用时自动调用它
不能链式执行
烧水泡茶中,通过构造函数传参做到多个任务的链式执行,万一有更多的任务,或是任务链的执行顺序有变,对原有程序的影响都是非常大的
整合多个 Future 执行结果方式笨重
假设有多个 Future 并行执行,需要在这些任务全部执行完成之后做后续操作,Future 本身是做不到的,需要借助工具类 Executors
的方法
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
没有异常处理
Future 同样没有提供很好的异常处理方案
上一篇文章看 Future 觉得是发现了新天地,这么一说有感觉回到了解放前
对于 Java 后端的同学,在 Java1.8 之前想实现异步编程,还想避开上述这些烦恼,ReactiveX 应该是一个常见解决方案(做Android 的应该会有了解)。如果熟悉前端同学, ES6 Promise(男朋友的承诺)也解决了异步编程的烦恼
天下语言都在彼此借鉴相应优点,Java 作为老牌劲旅自然也要解决上述问题。又是那个男人,并发大师 Doug Lea 忧天下程序员之忧,解天下程序员之困扰,在 Java1.8 版本(Lambda 横空出世)中,新增了一个并发工具类 CompletableFuture,它的出现,让人在泡茶过程中,品尝到了不一样的味道......
几个重要 Lambda 函数
CompletableFuture 在 Java1.8 的版本中出现,自然也得搭上 Lambda 的顺风车,为了更好的理解 CompletableFuture,这里我需要先介绍一下几个 Lambda 函数,我们只需要关注它们的以下几点就可以:
- 参数接受形式
- 返回值形式
- 函数名称
Runnable
Runnable 我们已经说过无数次了,无参数,无返回值
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Function
Function<T, R> 接受一个参数,并且有返回值
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Consumer
Consumer 接受一个参数,没有返回值
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
Supplier
Supplier 没有参数,有一个返回值
@FunctionalInterface
public interface Supplier<T> {
T get();
}
BiConsumer
BiConsumer<T, U> 接受两个参数(Bi, 英文单词词根,代表两个的意思),没有返回值
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
好了,我们做个小汇总
有些同学可能有疑问,为什么要关注这几个函数式接口,因为 CompletableFuture 的函数命名以及其作用都是和这几个函数式接口高度相关的,一会你就会发现了
前戏做足,终于可以进入正题了 CompletableFuture
CompletableFuture
类结构
老规矩,先从类结构看起:
实现了 Future 接口
实现了 Future 接口,那就具有 Future 接口的相关特性,请脑补 Future 那少的可怜的 5 个方法,这里不再赘述,具体请查看 不会用Java Future,我怀疑你泡茶没我快