我对守护程序线程感到困惑。在大多数站点中,写入它会在应用程序停止时终止,但如果应用程序连续运行会怎样。
答案 0 :(得分:7)
...但是如果应用程序连续运行会怎样。
然后守护程序线程继续运行。
(这假设有问题的线程不会从其run()
方法返回,或因未捕获的异常而死亡。)
将线程标记为"守护进程"是告诉JVM在启动关闭之前不需要等待线程完成。 (关闭的另一种方法是使用一些线程调用System.exit()
。即使存在其他非守护程序线程,也会启动关闭。)
<强>后续
我有一个在tomcat服务器下连续运行的应用程序,我从注释中推断出守护程序线程创建的注释不会因为应用程序没有停止而停止,但是如果我们尝试直接停止tomcat服务器,那么会创建内存泄漏?
如果停止webapp(但不是tomcat服务器),则守护程序线程将继续运行。如果你想让你的webapp创建的线程消失,你必须编写你的webapp来监听相关的上下文事件,并中断(或其他)线程使它们关闭。
如果关闭tomcat,那么一切都会消失,包括守护程序线程:
当您成功停止tomcat服务器时(例如&#34; catalina.sh stop&#34;)然后JVM退出并且所有线程(守护程序或其他)死亡。
跑步&#34; catalina.sh停止&#34; 可以失败,但仅仅存在一个守护程序线程不会导致它失败。
无法停止可能是由于某些webapp在其关闭事件处理中陷入困境,或者可能是由于tomcat服务器处于挂起或无响应状态。在至少某些版本的Tomcat中,非守护程序线程的存在足以导致关闭失败。)
如果你运行&#34; catalina.sh stop -force&#34;如果tomcat实例在5秒内无法关闭,则会被杀死;看&#34; catalina.sh帮助&#34;或者剧本的来源。
当您关闭并重新启动tomcat时,线程泄漏和内存泄漏都没有实际意义。实际上,这是泄漏的经典解决方法。
答案 1 :(得分:5)
正确。只有在所有非守护程序线程完成后,应用程序才会退出。这不适用于守护程序线程。
澄清:
public static void main(String[] args) {
Thread thread = new Thread() {
@Override
public void run() {
while (true) {
// do something...
}
}
}
thread.setDaemon(true);
thread.start();
}
以上将立即退出。但是,如果省略thread.setDaemon(true),程序将不会终止。
答案 2 :(得分:2)
守护程序线程在其run方法返回时停止,或者在JVM中不再运行非守护程序线程时停止。如果永远运行非守护程序线程,并且守护程序线程的run方法永远不会返回,那么守护程序线程也会永远运行。