【问题标题】:How does daemon thread survive after JVM exits?JVM退出后daemon线程如何存活?
【发布时间】:2015-09-23 23:26:06
【问题描述】:

我正在阅读有关 Java 的 setDaemon() 方法的文档,当我读到 JVM 退出而不等待守护线程完成时感到困惑。

但是,由于守护线程本质上是 Java Thread 的,可能依赖于在 JVM 上运行来实现其功能,如果 JVM 在守护线程完成之前退出,守护线程如何生存?

【问题讨论】:

  • 您只是误解了 等待守护线程完成 的含义。完成意味着完全执行他们的Runnablerun 方法。
  • 哪里说他们活下来了?你的问题没有意义,

标签: java multithreading parallel-processing jvm daemon


【解决方案1】:

他们无法生存。当所有线程(守护进程除外)都已死亡时,JVM 将退出。

当您启动应用程序时,JVM 将启动一个非守护线程来运行您的静态 main 方法。

一旦 main 方法退出,这个主线程就会死掉,如果你没有生成其他非守护线程,JVM 就会退出。

如果你启动了另一个线程,JVM 不会退出,它会等待所有非守护线程都死掉后再退出。

如果你生成的线程正在做一些重要的事情,这绝对是正确的做法,但通常你有一些不那么重要的线程,也许他们正在监听一些可能发生或可能不会发生的外部事件。

因此,理论上,您应该在某处放置一些代码来停止您生成的所有线程以允许 JVM 退出。

由于这很容易出错,因此将这些非重要线程标记为守护程序会更容易。如果它们被标记为这样,JVM 将不会等待它们在退出之前死亡,当“主线程”(那些未标记为守护进程的线程)死亡时,JVM 将退出并杀死这些线程。

把它放在代码中,它是这样的:

public class Spawner {
  public static void main(String[] args) {
    Thread t = new Thread(new Runnable() {
      public void run() {
        while (true) {
          System.out.println("I'm still alive");
        }
      }
    });
    // Try uncommenting/commenting this line
    // t.setDaemon(true);
    t.start();
    System.out.println("Main thread has finished");
  }
}

(这段代码我没测试过,直接写到这里,可能会有愚蠢的错误)。

当运行此代码并带有注释的行时,线程不是守护程序,因此即使您的 main 方法已完成,您仍将继续让控制台被淹没,直到您使用 CTRL+C 将其停止。即JVM不会退出。

如果取消注释该行,则线程是一个守护进程,并且在 main 方法完成后不久,线程将被终止,JVM 将退出,无需 CTRL+C。

【讨论】:

  • 如果我想让某个端口上的侦听器捕获某些事件怎么办?听起来一旦JVM退出监听器就会被杀死,那么我是否只是失去了我的监听器?
  • 是的,如果JVM存在,你的程序就完成了,所有的资源都被释放了,所以你不再监听任何端口了。
  • 不过,这更像是一个系统编程问题。基本上,操作系统在进程退出时会做什么。这不是 java 特有的。
  • 此答案中有关来自 JCIP 的守护程序线程的一些其他详细信息:stackoverflow.com/a/2213443/1155984
  • t.setDaemon(true) 应该在 t.start() 之前;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
相关资源
最近更新 更多