我有以下代码从主线程调用,使用ExecutorService池并启动一个线程来处理找到的每个文件。 当主线程被kill命令终止时,我试图了解ExecutorService的行为。产生的线程会怎样?他们是立即被杀害还是在完成工作后辞职?
还有什么更好/更安全的方法来编写以下代码段,尤其是如果我要在无限循环中运行此部分时,例如,等待将文件拖放到输入目录并分配线程来处理它们?在那种情况下,我应该在每次循环迭代中创建一个新的Pool和.awaitTermination
吗?
非常感谢
ExecutorService executorService = Executors.newFixedThreadPool(maxThreads);
for (File inputFile : inputDir.listFiles()) {
if (inputFile.isFile())
executorService.submit(new MyRunnable(inputFile));
}
executorService.shutdown();
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
答案 0 :(得分:2)
当主线程被kill命令终止时。产生的线程会怎样?
主线程不会被杀死(如果您从命令行使用kill <pid>
),但是JVM被杀死了,在这种情况下,终止会影响所有正在运行的线程。您可以设置关机处理程序,如果收到终止信号(不是kill -9
),则将触发该处理程序。参见:https://stackoverflow.com/a/2541618/179850
在那种情况下,我应该在每次循环迭代中创建一个新的Pool和.awaitTermination吗?
不。我要做的是将作业提交到循环外部开始的线程池,但将Future
返回的executorService.submit(...)
保留在循环的内部 中。您可以执行以下操作来等待每个作业完成。您可以在这里处理一些例外情况:
// this is all inside of the loop with the executorService created outside of loop
List<Future<?>> futures = new ArrayList<>();
for (File inputFile : inputDir.listFiles()) {
if (inputFile.isFile())
futures.add(executorService.submit(new MyRunnable(inputFile)));
}
}
// now we go back and wait for the jobs to finish
for (Future<?> future : futures) {
// this waits for each job to finish
// it throws some exceptions that you'll need to catch and handle
future.get();
}
答案 1 :(得分:1)
如果主线程已完成,崩溃,进入睡眠状态……只要您的逻辑未与之耦合,这不会影响其他线程。它们是独立的,它们会继续为您完成工作(只要它们不是JVM不优先的恶魔线程,并且仅剩下恶魔线程就可以完成该过程)。您维护了:
以终止命令终止
如果这意味着要杀死PID /杀死JVM进程,那么是的,所有线程都将由应用程序本身关闭。