我正在阅读有关Java setDaemon()
方法的文档,当我读到JVM退出而不等待守护程序线程完成时,我感到困惑。
但是,由于本质上守护程序线程是Java Thread
,它可能依赖于在JVM上运行来实现其功能,如果JVM在守护程序线程完成之前退出,守护程序线程如何能够存活?
答案 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.