ExecutorService-主线程关闭

时间:2018-10-19 07:39:42

标签: java multithreading executorservice

我有以下代码从主线程调用,使用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);

2 个答案:

答案 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进程,那么是的,所有线程都将由应用程序本身关闭。