简介
* CompletableFuture 用于 Java 中的异步编程 asynchronous。
* 异步编程是一种编写非阻塞代码的方法,方法是在与主应用程序不同的线程上运行任务,并通知主线程其进度、完成或失败。
runAsync 异步执行,无返回值
supplyAsync 异步执行,有返回值
在异步asynchronous模型中,允许同一时间发生(处理)多个事件。程序调用一个耗时较长的功能(方法)时,它并不会阻塞程序的执行流程,
程序会继续往下执行。当功能执行完毕时,程序能够获得执行完毕的消息或能够访问到执行的结果(如果有返回值或需要返回值时)。
加Async的是指CompletableFuture会把下边的代码看成两个独立的任务来执行,也就是会有两个子线程执行。
import java.util.concurrent.CompletableFuture;
一个Future类是显示的完成,而且能被用作一个完成等级,通过它的完成触发支持的依赖函数和行为。当两个或多个线程要执行完成或取消操作时,只有一个能够成功。
CompletableFuture首先是一个Future,它拥有Future所有的功能,包括获取异步执行结果,取消正在执行的任务等。
public class CompletableFuture<T> implements Future<T>, CompletionStage<T>
既然CompletableFuture类实现了CompletionStage接口。它代表了一个特定的计算的阶段,可以同步或者异步的被完成。你可以把它看成是一个计算流水线上的一个单元,最终会产生一个最终结果,这意味着几个CompletionStage可以串联起来,一个完成的阶段可以触发下一阶段的执行,接着触发下一次。
除了实现CompletionStage接口,CompletableFuture也实现了future接口, 代表一个未完成的异步事件。CompletableFuture提供了方法,能够显式地完成这个future,所以它叫CompletableFuture。
CompletableFuture
使用Future
获得异步执行结果时,要么调用阻塞方法get()
,要么轮询看isDone()
是否为true
,这两种方法都不是很好,因为主线程也会被迫等待。
从Java 8开始引入了CompletableFuture
,它针对Future
做了改进,可以传入回调对象,当异步任务完成或者发生异常时,自动调用回调对象的回调方法。
加Async的是指CompletableFuture会把下边的代码看成两个独立的任务来执行,也就是会有两个子线程执行。
public class Main {
public static void main(String[] args) throws Exception {
// 创建异步执行任务:
CompletableFuture<Double> cf = CompletableFuture.supplyAsync(Main::fetchPrice);
// 如果执行成功:
cf.thenAccept((result) -> {
System.out.println("price: " + result);
});
// 如果执行异常:
cf.exceptionally((e) -> {
e.printStackTrace();
return null;
});
// 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
Thread.sleep(200);
}
static Double fetchPrice() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
if (Math.random() < 0.3) {
throw new RuntimeException("fetch price failed!");
}
return 5 + Math.random() * 20;
}
}