CompletableFuture打开方式

2019-11-03  本文已影响0人  但时间也偷换概念

前言:

Future模式是CompletableFuture的基础,Future模式有哪些应用场景呢?

超时控制场景、多异步任务并行处理、客户端异步等

有过研究的读者应该会想到,很多rpc框架中可以通过future先挂起一个线程,然后阻塞得到结果,这个过程也可以做超时控制。

还有JetCache这种缓存框架,返回值会是一个CompletionStage对象,这样也可以做一些异步操作并且保证用户线程不会持续阻塞下去。

其实Future模式应该说是一种aio思想,但是Java 8 之前Future这个类,会有一些问题。

首先Future写法麻烦,并且不支持链式,其次就是Future一定要阻塞住,并不支持anyOf这种操作,再者,Future在组合上的写法也很丑陋。

于是开发者有很多转向google guava提供的ListenableFuture类。

我之前几篇blog都说过,Oracle经常借鉴google类库,于是Java 8 中提供了增强版Future,也就是CompletableFuture。

说完了背景,我们来看CompletableFuture如何使用,以及使用时我们应该注意哪些方面。

1.1 启动一个异步线程

public static CompletableFuture runAsync(Runnable runnable)

public static CompletableFuture runAsync(Runnable runnable, Executor executor)

public static CompletableFuture supplyAsync(Supplier supplier)

public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)

CompletableFuture提供的这几个api是最常见的创建异步任务方式。

runAsync一般用于无返回值的。

supplyAsync用于有返回值处理的。

重载方法是支持传入用户自定义的线程池开启线程,而CompletableFuture默认的线程池是一个根据cpu自适应的ForkJoin池。

runAsync

1.2 CompletableFuture组合

supplyAsync

链式组合是Java 8 、 Guava、Spring近几年主推的编程范式。

我们可以看到,CompletableFuture支持链式传递,将上一个异步任务的结果作为下一个异步任务的参数,进行异步任务组合编程,这里有很多api,留给读者自己实验。

1.3 CompletableFuture批量处理

allOf

allOf

anyOf

anyOf

看到这里聪明的读者已经想到了,allOf适合的场景就是主线程需要等待所有异步任何都结束再进行下一步操作。

anyOf适合的是不需要等待所有异步任务都结束,就可以继续往下走。

这个地方其实就是整合了Future + CountDownLatch | CyclicBarrier 有木有?

所以说CompletableFuture真的提供了很大的便利,让我们可以轻松实现高级的异步。

1.4 CompletableFuture异常处理

1.4.1 completeExceptionally

completeExceptionally

1.4.1 exceptionally

exceptionally

如果是有返回值的supplyAsync,只需要在exceptionally里面return异常情况返回值即可。

总结

1.Future模式是一种异步思想,主线程可以过段时间再来阻塞获取异步结果。

2.Future的局限性衍生了ListenableFuture、NettyFuture等产品。

3.Java 8 推出了增强版Future CompletableFuture。

4.CompletableFuture默认使用ForkJoin线程池,但更推荐自实现线程池开启CompletableFuture。(性能方面&安全方面更佳)

5.CompletableFuture可以链式组合多异步任务,可以将上个任务处理结果当作参数传递给下一个异步任务,并且支持allOf、anyOf这种批量管理操作。

6.CompletableFuture异常处理支持lambda、completeExceptionally两种方式。

7.在CompletableFuture阻塞获取结果时,谨记增加最长时间限制,以及try catch处理,在InterruptedException catch中中断当前线程。

8.CompletableFuture join函数慎用,将无限阻塞下去。

上一篇下一篇

猜你喜欢

热点阅读