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?
某草草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
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:
defaultForkJoinWorkerThreadFactory = new DefaultForkJoinWorkerThreadFactory();
Look at his implementation and create a daemon process every time. As for why the main thread must sleep, it is easy to understand.