4

我最近需要向我拥有的 Scala 应用程序添加一个关闭挂钩,我发现 Scala 为此提供了一个名为ShutdownHookThread的帮助程序。在其源代码中,我注意到它将新线程设置为守护线程

def apply(body: => Unit): ShutdownHookThread = {
  val t = new ShutdownHookThread(hookName()) {
    override def run() = body
  }
  t setDaemon true  // <--------- right here
  runtime addShutdownHook t
  t
}

为什么这样做?在我看来,您可能希望在关闭挂钩线程中相反(即确保线程在关闭 jvm 之前退出)。还是守护进程/非守护进程与关闭挂钩无关?

4

2 回答 2

5

在 JVM 上,通常一个非守护线程会阻止 JVM 终止。一旦不再有任何非守护线程,JVM 将通过启动关闭来优雅地终止。有关更多信息,请参阅addShutdownHook javadoc

启动关机后,我不确定守护程序状态是否重要。在启动关闭之前,关闭钩子线程也不会启动。所以在这种情况下t setDaemon true可能是不必要的,但它也不会受到伤害。

所以简而言之,“守护进程”语义与 unix 不同(在 unix 领域,它表示一个继续运行的线程)。

于 2011-10-14T14:26:52.123 回答
1

在这里回答我自己的问题。

两部分:

  1. 为什么ShutdownHookThread让它的新线程daemon=true?
  2. 如果关闭挂钩线程是 daemon=true,会发生什么?

答案:

  1. 这源于对“Scala 脚本”的要求(scala myfile.scala首先运行而不是显式编译)。在这里讨论。它现在已更改(commit),因此未来版本ShutdownHookThread不会有此代码。
  2. 我还没有发现任何决定性的东西,但从实验上看,这似乎并不重要。我认为这是有道理的,因为守护进程状态会影响 JVM 何时开始关闭,因此在关闭已经开始之后,守护进程状态应该无关紧要。
于 2011-10-25T21:26:46.497 回答