日常开发中,我们都会用到线程池,一般会用execute()和submit()方法提交任务。但是当你用过CompletableFuture之后,就会发现以前的线程池处理任务有多难用,功能有多简陋,CompletableFuture又是多么简洁优雅。
要知道CompletableFuture已经随着Java8发布7年了,还没有过它就有点说不过去了。
一、线程池处理任务和CompletableFuture处理任务
输出结果:
这里能够发现两个问题:
有没有具体的优化方案呢?当然有了,请出来我们今天的主角CompletableFuture
输出结果:
可以看到是ComparableFutrue是通过supplyAsync方法进行异步执行任务的。
=============================================================
可是上面的任务执行还是有一些问题的,需要阻塞当前线程输出结果,但是我们并不能确定线程的执行结束时间。也就无法准确设置线程阻塞时间,这样子就会导致最后执行的结果不对。
我们可以通过join进行优化一下:异步任务完成时统一返回结果值
代码中使用了CompletableFuture的两个方法:
supplyAsync()方法作用是提交异步任务,有两个传参,任务和自定义线程池。
whenCompleteAsync()方法作用是异步获取结果,也有两个传参,结果和异常信息。
代码经过CompletableFuture改造后,是多么的简洁优雅。
提交任务也不用再关心线程池是怎么使用了,获取结果也不用再阻塞当前线程了。
==============================================================
又或者可以通过Java8的Stream流进进一步简化test2的代码:
二、CompletableFuture更多使用
第一种:使用CountDownLatch方式
第二种:使用CompletableFuture
打印结果:
这里需要说明的一点是,我这边使用了 CopyOnWriteArrayList,因为是在多线程环境下,如果使用ArrayList会导致有数据无法成功添加到集合中。
代码看着有点乱,其实逻辑很清晰。
CompletableFuture的 allOf()方法的作用就是,等待所有任务处理完成。
如果要实现这样一个需求,往线程池提交一批任务,只要有其中一个任务处理完成就返回。
该怎么做?如果你手动实现这个逻辑的话,代码肯定复杂且低效,有了CompletableFuture就非常简单了,只需调用 anyOf()方法就行了
执行结果:
执行结果:
代码主要用到了CompletableFuture的 thenApplyAsync()方法,作用就是异步处理上一个线程的结果。
三、CompletableFuture常用API
提交任务:
- supplyAsync
- runAsync
接力处理:
- thenRun thenRunAsync
- thenAccept thenAcceptAsync
- thenApply thenApplyAsync
- handle handleAsync
- applyToEither applyToEitherAsync
- acceptEither acceptEitherAsync
- runAfterEither runAfterEitherAsync
- thenCombine thenCombineAsync
- thenAcceptBoth thenAcceptBothAsync
获取结果:
- join 阻塞等待,不会抛异常
- get 阻塞等待,会抛异常
- complete(T value) 不阻塞,如果任务已完成,返回处理结果。如果没完成,则返回传参value。
- completeExceptionally(Throwable ex) 不阻塞,如果任务已完成,返回处理结果。如果没完成,抛异常。
总结分类
带 run的方法, 无入参,无返回值。
带 accept的方法, 有入参,无返回值。
带 supply的方法, 无入参,有返回值。
带 apply的方法, 有入参,有返回值。
带 handle的方法, 有入参,有返回值,并且带异常处理。
以 Async结尾的方法,都是 异步的,否则是同步的。
以 Either结尾的方法,只需完成任意一个。
以 Both/Combine结尾的方法,必须所有都完成。
输出结果可能是:
也可能是:
打印结果是:
如果去掉sleep语句,那么打印的就是:
输出结果可能是:’饭做好了’,也有可能是’外卖到了’
Original: https://www.cnblogs.com/zhangzhixi/p/16624757.html
Author: Java小白的搬砖路
Title: CompletableFuture的简单使用
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/575250/
转载文章受原作者版权保护。转载请注明原作者出处!