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秒呢?
見
CompletableFuture.supplyAsync
的javadoc:而
ForkJoinPool.commonPool()
的javadoc:如果你把最後的
sleep
改成ForkJoinPool.commonPool().awaitQuithesis(2, TimeUnit.SECONDS);
也能達到你預期的結果搜尋一下:守護線程
當線程中只剩下守護線程時JVM就會退出,反之亦然還有任意一個用戶線程在,JVM都不會退出。
我們可以猜測CompletableFuture.supplyAsync啟動了一個守護線程,實際上CompletableFuture內部預設使用ForkJoinPool,該線程池初始化一個線程工廠類別:
查看他的實現,每次都是創建守護程式。至於為什麼一定要主線程sleep就很好理解。