我正在比较 CompletableFuture.supplyAsync() 在我设置自定义 ExecutorService 或我希望我的供应商由默认执行器(如果未指定)是ForkJoinPool.commonPool()
让我们看看区别:
public class MainApplication {
public static void main(final String[] args) throws ExecutionException, InterruptedException {
Supplier<String> action1 = () -> {
try {
Thread.sleep(3000);
}finally {
return "Done";
}
};
Function<String, String> action2 = (input) -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
return input + "!!";
}
};
final ExecutorService executorService = Executors.newFixedThreadPool(4);
CompletableFuture.supplyAsync(action1, executorService)
.thenApply (action2)
.thenAccept (res -> System.out.println(res));
System.out.println("This is the end of the execution");
}
}
在本例中,我将 executorService 传递给我的 SupplyAsync() 并打印:
This is the end of the execution
Done!!
因此主执行结束后会打印“Done”。
但是如果我使用:
CompletableFuture.supplyAsync(action1)
所以我不传递我的自定义 executorService 并且 CompletableFuture 类在底层使用 ForkJoinPool.commonPool() 那么“Done”根本不会打印:
This is the end of the execution
Process finished with exit code 0
为什么?
最佳答案
在这两种情况下,当您这样做时
CompletableFuture.supplyAsync(action1, executorService)
.thenApply (action2)
.thenAccept (res -> System.out.println(res));
您无需等待任务完成。但随后你的程序将退出,并且常见的 fork join 池存在差异:
ForkJoinPool.commonPool()
和常规执行者服务:
final ExecutorService executorService = Executors.newFixedThreadPool(4);
..对尝试调用 System.exit(...) 等效项使用react。
这就是 doc says关于fork join common pool,需要注意的是:
However this pool and any ongoing processing are automatically terminated upon program System.exit(int). Any program that relies on asynchronous task processing to complete before program termination should invoke commonPool().awaitQuiescence, before exit.
这是指向 ExecutorService docs 的链接,您可以关注:
The shutdown() method will allow previously submitted tasks to execute before terminating
我认为这可能是您所问的差异。
关于java - CompletableFuture.supplyAsync() 中 ForkJoinPool 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54035090/