ExecutorService - 主线程的关闭

ExecutorService - shutdown of main thread

我从主线程调用下面的代码,使用 ExecutorService 池并启动一个线程来处理找到的每个文件。 当主线程被 kill 命令终止时,我试图了解 ExecutorService 的行为。生成的线程会怎样?他们是立即被杀死还是在完成工作后终止?

还有什么 better/safer 方法可以编写下面的代码片段,特别是如果我要 运行 这部分在无限循环中,例如等待文件被放到输入目录和分配线程来处理它们?在那种情况下,我应该在每次循环迭代中创建一个新的 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);

如果主线程完成、崩溃、休眠...只要您的逻辑不与其耦合,就不会影响其他线程。它们是独立的,它们将继续为您完成工作(只要它们不是 JVM 未优先考虑的恶魔线程,并且该过程将完成,只剩下恶魔线程)。您维护了:

terminated by a kill command

如果这意味着终止 PID/终止 JVM 进程,那么是的,所有线程都将与应用程序本身一起关闭。

when the main thread gets terminated by a kill command. What happens to the spawned threads?

主线程没有被终止(如果你的意思是从命令行 kill <pid>),但是 JVM 被终止,在这种情况下,终止会影响所有线程 运行。您可以设置关闭处理程序,如果收到终止信号(不是 kill -9),将被触发。参见:

In that case should I be creating a new Pool and .awaitTermination in each loop iteration ?

没有。我要做的是将你的作业提交到循环外启动的线程池,但将 executorService.submit(...) 返回的 Futures 保存在 inside 的集合中环形。您可以执行类似以下的操作来等待每个作业完成。这里有例外情况需要您处理:

// 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();
}