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

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

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

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

如果JVM退出,守护进程将无法生存。

无论是否是守护进程,Java线程都在Java虚拟机上运行。 如果虚拟机死机,其上运行的每个Java线程都会死掉,包括守护进程线程。

Java中的守护程序线程是那些在后台运行的线程,主要由JVM创建,用于执行垃圾收集和其他内务处理任务等后台任务。

一旦所有用户线程完成执行java程序或JVM终止自身,JVM就不会等待守护程序线程完成执行。 无论有多少守护程序线程存在或在JVM内运行,最后一个非守护程序线程完成JVM终止。

注意:守护程序线程在关闭时不会中断,也不一定会调用它们的finalize()方法。

您始终可以向JVM运行时添加关闭挂钩:

 Thread shutdownHook = ... // construct a thread that performs graceful // shutdown of JVM Runtime.getRuntime().addShutdownHook(shutdownHook); 

shutdown hook可以根据需要正常关闭守护程序线程。