JVM退出后,守护程序线程如何生存?

时间:2015-07-06 17:38:55

标签: java multithreading parallel-processing jvm daemon

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

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

1 个答案:

答案 0 :(得分:19)

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

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

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

如果你启动了另一个线程,JVM将不会退出,它将等待所有非守护进程线程在退出之前死掉。

如果你产生的那个线程正在做一些重要的事情,这绝对是正确的事情,但是你经常会遇到一些并不重要的线程,也许他们正在听一些可能会或可能不会发生的外部事件。 / p>

因此,理论上,您应该在某处放置一些代码来阻止您生成的所有线程以允许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");
        }
      }
    });
    t.start();
    // Try uncommenting/commenting this line
    // t.setDaemon(true);
    System.out.println("Main thread has finished");
  }
}

(我没有测试过这段代码,直接写在这里,所以它可能包含愚蠢的错误)。

当使用注释行运行此代码时,线程不是deamon,所以即使你的main方法已经完成,你将继续让控制台泛滥,直到用CTRL + C停止它。也就是说,JVM不会退出。

如果你取消注释该行,那么该线程就是一个守护进程,在main方法完成后不久,该线程将被终止并且JVM将退出,而不需要CTRL + C.