java中的守护线程

  • 本文关键字:线程 守护 java java
  • 更新时间 :
  • 英文 :


我对守护线程感到困惑。在大多数站点中,它被写为当应用程序停止时终止,但如果应用程序持续运行呢?

…但是如果应用程序是连续运行的呢?

然后守护线程继续运行。

(这假设所讨论的线程没有从其run()方法返回,或者由于未捕获的异常而死亡。)

将线程标记为"守护进程"的意义在于告诉JVM,它不需要在启动关闭之前等待线程完成。(另一种关闭的方法是让一些线程调用System.exit()。这将启动关机,即使存在其他非守护线程。


如果线程正在运行,我在一个web应用程序中使用它,会停止服务器的影响吗?

是的。假设"停止服务器"意味着做一些导致webserver/webcontainer JVM退出的事情,那么任何线程都将死亡。


我有一个在Tomcat服务器下持续运行的应用程序,我从注释中推断,创建的守护线程不会停止,因为应用程序没有停止,但是如果我们试图直接停止Tomcat服务器,会产生内存泄漏吗?

如果你停止webapp(而不是tomcat服务器),那么守护线程将继续运行。后续版本的Tomcat会产生警告消息。

如果你想让你的webapp创建的线程消失,你必须编程你的webapp来监听相关的上下文事件,并中断(或其他)线程,使它们关闭。

如果您关闭Tomcat,那么一切都将消失,包括守护线程:

  1. 当您成功停止tomcat服务器(例如catalina.sh stop)时,JVM退出,所有线程(守护进程或其他)死亡。

  2. 运行catalina.sh stop 可能会失败,但是仅仅存在一个守护线程不会导致它失败。

    停止失败可能是由于某些web应用程序在其关闭事件处理中卡住,或者可能是由于Tomcat服务器处于挂起或无响应状态。至少在某些版本的Tomcat中,非守护线程的存在就足以导致关机失败。

  3. 如果你运行catalina.sh stop -force,那么如果Tomcat实例在5秒内没有关闭,它将被杀死;参见catalina.sh help或脚本的源代码

当您关闭并重启Tomcat时,任何线程泄漏和内存泄漏都是没有意义的。实际上,这是解决泄漏的经典方法。

正确。只有当所有非守护线程都完成时,应用程序才会退出。

澄清:

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),程序将不会终止。

守护线程在其run方法返回时停止,或者在JVM中不再运行非守护线程时停止。如果有一个非守护线程永远运行,并且守护线程的run方法永远不会返回,那么守护线程也永远运行。

最新更新