记录在工作中遇到 一个页面的报表统计接口,因为数据组成有很多方面,每个方面对应的是一个方法,问题点:因为我的子方法涉及的有6个,怎么来减少等待时间? 处理办法就是,利用多线程,异步处理并带返回值,接下来我们利用CompletableFuture 来完成此业务。
1. CompletableFuture介绍
Future模式的缺点
Future虽然可以实现获取异步执行结果的需求,但是它没有提供通知的机制,我们无法得知Future什么时候完成。
要么使用阻塞,在future.get()的地方等待future返回的结果,这时又变成同步操作。要么使用isDone()轮询地判断Future是否完成,这样会耗费CPU的资源。
CompletableFuture介绍
Netty、Guava分别扩展了Java 的 Future 接口,方便异步编程。
Java 8新增的CompletableFuture类正是吸收了所有Google
Guava中ListenableFuture和SettableFuture的特征,还提供了其它强大的功能,让Java拥有了完整的非阻塞编程模型:Future、Promise
和 Callback(在Java8之前,只有无Callback 的Future)。CompletableFuture能够将回调放到与任务不同的线程中执行,也能将回调作为继续执行的同步函数,在与任务相同的线程中执行。它避免了传统回调最大的问题,那就是能够将控制流分离到不同的事件处理器中。
CompletableFuture弥补了Future模式的缺点。在异步的任务完成后,需要用其结果继续操作时,无需等待。可以直接通过thenAccept、thenApply、thenCompose等方式将前面异步处理的结果交给另外一个异步事件处理线程来处理。
2. CompletableFuture使用场景
3.创建异步任务
- supplyAsync执行CompletableFuture任务,支持返回值
//使用默认内置线程池ForkJoinPool.commonPool(),根据supplier构建执行任务
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
//自定义线程,根据supplier构建执行任务
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
- runAsync执行CompletableFuture任务,没有返回值。
//使用默认内置线程池ForkJoinPool.commonPool(),根据runnable构建执行任务
public static CompletableFuture<Void> runAsync(Runnable runnable)
//自定义线程,根据runnable构建执行任务
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor