在主线程退出后,守护程序线程在java中是否有可能继续?

时间:2012-01-12 10:23:13

标签: java multithreading daemon

我在Eclipse嵌入式Tomcat中运行多线程Web应用程序。有些线程是守护进程,有些则不是。 我跑完之后:

shutdown.bat

我看到有些线程完成了工作,但有些仍然存在!奇怪的是,剩下的线程是守护进程线程(我在Eclipse的调试视图中看到过)。但这是不可能的 - 我没有看到主线程,但看到守护线程!它是否与特定的Tomcat Web容器相关联,或者它可能是我的Web应用程序的问题? 谢谢。 或者它特定于Eclipse嵌入式Tomcat?

3 个答案:

答案 0 :(得分:3)

是。所有非守护程序线程完成后,程序退出。如果main启动一个正在运行的非守护程序线程,那么使用名为“main”exit的线程不会执行任何操作。

答案 1 :(得分:1)

这是一个简单的证据。如果所有非主线程都是守护进程,那么一旦主线程死掉它们就会死掉:

class DaemonTask implements Runnable {

  private final int id;
  private final Thread main;

  DaemonTask(int id, Thread main) {

    this.id = id;
    this.main = main;
  }

  @Override
  public void run() {

    while (true) {

      System.out.println((Thread.currentThread().isDaemon() ? "" : "non") + " daemon id = " + id + "; main alive: " + main.isAlive());
      try {
        Thread.sleep(100L * id);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

for (int i = 0; i < 10; i++) {

  Thread t = new Thread(new DaemonTask(i + 1, Thread.currentThread()));
  t.setDaemon(true);
  t.start();
}

System.out.println("main finishing");

输出:

main finishing
 daemon id = 6; main alive: true
 daemon id = 3; main alive: true
 daemon id = 2; main alive: true
 daemon id = 10; main alive: true
 daemon id = 9; main alive: false
 daemon id = 8; main alive: false
 daemon id = 4; main alive: false
Process finished with exit code 0

如果我们在离开主线程之前创建并启动非守护程序线程:

new Thread(new DaemonTask(100, Thread.currentThread())).start();

应用程序将继续运行:

main finishing
 daemon id = 2; main alive: true
 daemon id = 1; main alive: true
 daemon id = 3; main alive: false
 daemon id = 4; main alive: false
 daemon id = 5; main alive: false
 daemon id = 7; main alive: false
 daemon id = 6; main alive: false
non daemon id = 100; main alive: false
 daemon id = 10; main alive: false
 daemon id = 9; main alive: false
 daemon id = 8; main alive: false
 daemon id = 1; main alive: false
 daemon id = 2; main alive: false
 daemon id = 1; main alive: false
 daemon id = 3; main alive: false
 daemon id = 1; main alive: false
 daemon id = 4; main alive: false
 daemon id = 2; main alive: false

答案 2 :(得分:1)

你正在运行一个调试器,这基本上意味着JVM终止的行为不像人们期望的那样。

很可能开发人员可能希望在JVM终止时检查守护程序线程。

这意味着调试器实际上是应用程序中的“主”线程,调试器不希望将其内部工作暴露给UI。想象一下在调试器代码本身中设置一个断点......我看到这可能会让事情变得混乱,因为你会锁定你的调试会话!

如果您没有使用调试器,请不要指望这种情况发生。