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

One*_*ero 9 java parallel-processing multithreading jvm daemon

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

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

Sim*_*nni 22

他们无法生存.当除守护进程之外的所有线程都已经死亡时,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");
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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