Java 为什么以下应用程序在使用ForkJoinPool时立即终止,而在我使用ThreadPoolExecutor时却不立即终止?
我试图理解ForkJoinPool和ThreadPoolExecutor之间的一些区别,下面的内容引起了我的注意 使用ThreadPoolExecutorJava 为什么以下应用程序在使用ForkJoinPool时立即终止,而在我使用ThreadPoolExecutor时却不立即终止?,java,multithreading,Java,Multithreading,我试图理解ForkJoinPool和ThreadPoolExecutor之间的一些区别,下面的内容引起了我的注意 使用ThreadPoolExecutor public static void main(String[] args) { ExecutorService es = Executors.newCachedThreadPool(); es.execute(() -> System.out.println("Hello.")); es.shutdown();
public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool();
es.execute(() -> System.out.println("Hello."));
es.shutdown();
}
此程序将始终在屏幕上打印“Hello.”
使用ForkJoinPool
public static void main(String[] args) {
ForkJoinPool es = new ForkJoinPool(1);
es.execute(() -> System.out.println("Hello."));
es.shutdown();
}
此程序有时会将“Hello.”打印到屏幕上
这是怎么回事
请注意,如果调用gracefully shutdown,第一个程序永远不会终止,但在其他方面,两个程序的行为相同
我理解,可以通过注意JVM根本不等待执行的线程终止来解释fork/join行为,有时线程幸运地在main完成之前运行。为什么第一个解决方案没有表现出相同的行为
我不认为答案是两者实际上表现相同,我只是在运行第一个解决方案时感到幸运。事实上,当我运行第一个解决方案100次时,我会得到100次“Hello.”,但当我运行第二个100次时,我会得到大约10次“Hello.”。即使“始终”一词并不完全正确,但这两个词的工作方式似乎有一个关键区别,导致了明显不同的行为。
ForkJoinPool
是用守护进程线程定义的。也就是说,FJP创建的每个线程都是setDaemon(true)
。一旦只有守护进程线程运行,JVM将立即终止
您可能应该
关闭
然后等待终止
令人惊讶的是,就我所见,它不在规范中。@Assylas我同意,我也同样感到惊讶。