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);
Das Ergebnis ist:
do something else
enter into completableFuture()
finalize...
start to out of completableFuture()
a b
Wenn Sie die letzte Zeile des obigen Codes auskommentieren, erhalten Sie nicht die erwarteten Ergebnisse.
Warum müssen wir das Programm explizit 10 Sekunden lang schlafen lassen?
见
CompletableFuture.supplyAsync
的javadoc:而
ForkJoinPool.commonPool()
的javadoc:如果你把最后的
sleep
改成ForkJoinPool.commonPool().awaitQuiescence(2, TimeUnit.SECONDS);
也能达到你预期结果搜索一下:守护线程
当线程中只剩下守护线程时JVM就会退出,反之还有任意一个用户线程在,JVM都不会退出。
我们可以猜测CompletableFuture.supplyAsync启动了一个守护线程,实际上CompletableFuture内部默认使用ForkJoinPool,该线程池初始化一个线程工厂类:
查看他的的实现,每次都是创建守护进程。至于为什么一定要主线程sleep就很好理解。