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);
The result is:
do something else
enter into completableFuture()
finalize...
start to out of completableFuture()
a b
If the last line of the above code is commented out, the expected results will not be obtained.
Why must we explicitly let the program sleep for 10 seconds?
见
CompletableFuture.supplyAsync
的javadoc:而
ForkJoinPool.commonPool()
的javadoc:如果你把最后的
sleep
改成ForkJoinPool.commonPool().awaitQuiescence(2, TimeUnit.SECONDS);
也能达到你预期结果Search for: daemon thread
The JVM will exit when only the daemon thread is left in the thread. Otherwise, if there is any user thread, the JVM will not exit.
We can guess that CompletableFuture.supplyAsync starts a daemon thread. In fact, CompletableFuture uses ForkJoinPool by default internally. This thread pool initializes a thread factory class:
Look at his implementation and create a daemon process every time. As for why the main thread must sleep, it is easy to understand.