Java 如何在退出应用程序时关闭所有执行者?

Java 如何在退出应用程序时关闭所有执行者?,java,concurrency,Java,Concurrency,根据Brian Goetz的Java并发实践,在所有(非aemon)线程终止之前,JVM无法退出,因此未能关闭执行器可能会阻止JVM退出 也就是说,如果周围有执行者,系统出口(0)不一定能按预期工作。似乎有必要采取某种措施 public void stop() { exec.shutdown() } 方法调用包含执行器的所有类,然后在应用程序即将终止时调用它们。这是唯一的方法,还是有某种捷径可以关闭所有的执行器?他可能是想说JVM不能自己停止,直到非Daemon线程完成。这就像从命令运行一个简

根据Brian Goetz的Java并发实践,在所有(非aemon)线程终止之前,JVM无法退出,因此未能关闭执行器可能会阻止JVM退出

也就是说,如果周围有执行者,系统出口(0)不一定能按预期工作。似乎有必要采取某种措施

public void stop() { exec.shutdown() }

方法调用包含执行器的所有类,然后在应用程序即将终止时调用它们。这是唯一的方法,还是有某种捷径可以关闭所有的执行器?

他可能是想说JVM不能自己停止,直到非Daemon线程完成。这就像从命令运行一个简单的类,比如javasomeclass,然后在主方法JVM停止执行之后


System.exit是一个JVM终止命令,即使守护进程线程正在运行,JVM也会关闭。

没有快捷方式来完成所有操作。此外,您可能应该调用
shutdownNow()
而不是
shutdown()
,否则您可能会等待一段时间

我想,你可以做的是,当你创建遗嘱执行人时,在一个中心位置注册它。然后,在关闭时,只需在该中心对象上调用
shutdown()
,这就可以终止每个已注册的执行器


如果您使用Spring,那么您可以利用它的工厂bean为您创建和管理执行器。这包括在应用程序退出时优雅地关闭它们,并节省您自己管理它们的时间。

您还可以提供一个ThreadFactory实现,将创建的线程标记为守护进程线程。我更喜欢干净的关闭机制(使用生命周期方法),但在某些情况下,如果合适的话,您不需要保证未完成任务的状态/完成。

默认情况下,执行器将只创建非守护进程线程。您可以通过向Executor提供自己的ThreadFactory来覆盖它。下面是一个例子:

class DaemonThreadFactory implements ThreadFactory {
  public Thread newThread(Runnable r) {
    Thread t = new Thread(r);
    t.setDaemon(true);
    return t;
  }
}

但是要小心,因为即使这些线程忙于做有用的工作,JVM也会立即退出

将给定的ThreadPoolExecutor转换为在应用程序完成时退出的ExecutorService。它通过使用守护进程线程并添加一个关闭钩子来等待它们的完成来实现

这主要用于固定线程池。请参阅Executors.newFixedThreadPool(int)


正如Goetz所写,非守护线程可以阻止JVM退出。事实上我也经历过。调试器显示应用程序可以无限次地阻塞System.exit(0),但这似乎是不确定的行为。通常不会堵塞,但有时会堵塞。中央寄存器似乎是一个合理的选择。有趣的是,java.util.concurrent没有包含这样的函数。令人遗憾的是,执行器只是一堆静态函数,这使得在不复制几十个方法签名的情况下很难将其隐藏在注册接口后面。我也面临着类似的问题。我没有明确使用ScheduledThreadPoolExecutor。因此,我没有任何中心参考相同。在这种情况下,如何访问这些线程池?我试图优雅地关闭它们在上下文中我混淆了Executor和Runnable。我删除了我的答案,因为它没有多大意义@斯卡夫曼有我的投票权。谢谢你指出这个选项。实际上,我的一些执行器应该是守护进程线程,它们恰好是非守护进程线程,因为默认情况下,executors.newxxxecutor():s就是这样做的。
@Beta
public static ExecutorService getExitingExecutorService(ThreadPoolExecutor executor,
                                         long terminationTimeout,
                                         TimeUnit timeUnit)