CompletableFuture 类声明了 CompletionStage 接口,CompletionStage 接口实际上提供了同步或异步运行计算的舞台。
所谓异步调用其实就是实现一个可无需等待被调用函数的返回值而让操作继续运行的方法。在 Java 语言中,简单的讲就是另启一个线程来完成调用中的部分计算,使调用继续运行或返回,而不需要等待计算结果。但调用者仍需要获取线程的计算结果。
CompletableFuture 简单的异步运算场景
CompletableFuture 提供了如下的异步方法,
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor) {
return asyncSupplyStage(screenExecutor(executor), supplier);
}
public static CompletableFuture<Void> runAsync(Runnable runnable) {
return asyncRunStage(asyncPool, runnable);
}
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) {
return asyncRunStage(screenExecutor(executor), runnable);
}
supplyAsync 返回带有任务结果的CompletableFuture,而runAsync返回CompletableFuture<Void>。
Executor
参数可以手动指定线程池,否则默认ForkJoinPool.commonPool()
系统级公共线程池。
注意:ForkJoinPool.commonPool()
是
Daemon Thread(守护线程)只要当前JVM实例中尚存在任何一个非守护线程(用户线程)没有结束,守护线程就全部工作;
只有当用户线程结束时,JVM推出,守护线程随着JVM一同结束工作。
@Test
public void test() throws InterruptedException {
CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
System.out.println("runAsync=" + Thread.currentThread().getName() + "|" + Thread.currentThread().isDaemon());
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("done=" + cf.isDone());
TimeUnit.SECONDS.sleep(4);
System.out.println("done=" + cf.isDone());
}
输出,
done=false
runAsync=ForkJoinPool.commonPool-worker-1|true
done=true
在这段代码中,runAsync 是异步执