CompletableFuture cf1 = CompletableFuture.supplyAsync(() -> {
System.out.println("enter into completableFuture()");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("start to out of completableFuture()");
return "a";
});
System.out.println("do something else");
cf1.thenApply(v -> v + " b").thenAcceptAsync(v ->
System.out.println(v)
);
System.out.println("finalize...");
//注释最后一行,无法得到预期结果
//TimeUnit.SECONDS.sleep(10);
得到引结果为:
do something else
enter into completableFuture()
finalize...
start to out of completableFuture()
a b
以上代码如果注释掉最后一行,无法得到预期结果。
为什么一定要显式的让程序sleep10秒呢?
某草草2017-06-15 09:24:15
见CompletableFuture.supplyAsync
的javadoc:
Returns a new CompletableFuture that is asynchronously completed by a task running in the
ForkJoinPool.commonPool()
with the value obtained by calling the given Supplier.
而ForkJoinPool.commonPool()
的javadoc:
Returns the common pool instance. This pool is statically constructed; its run state is unaffected by attempts to shutdown or shutdownNow. However this pool and any ongoing processing are automatically terminated upon program
System.exit
. Any program that relies on asynchronous task processing to complete before program termination should invokecommonPool().awaitQuiescence
, before exit.
如果你把最后的sleep
改成ForkJoinPool.commonPool().awaitQuiescence(2, TimeUnit.SECONDS);
也能达到你预期结果
某草草2017-06-15 09:24:15
搜索一下:守护线程
当线程中只剩下守护线程时JVM就会退出,反之还有任意一个用户线程在,JVM都不会退出。
我们可以猜测CompletableFuture.supplyAsync启动了一个守护线程,实际上CompletableFuture内部默认使用ForkJoinPool,该线程池初始化一个线程工厂类:
defaultForkJoinWorkerThreadFactory = new DefaultForkJoinWorkerThreadFactory();
查看他的的实现,每次都是创建守护进程。至于为什么一定要主线程sleep就很好理解。