我在Eclipse嵌入式Tomcat中运行多线程Web应用程序。有些线程是守护进程,有些则不是。 我跑完之后:
shutdown.bat
我看到有些线程完成了工作,但有些仍然存在!奇怪的是,剩下的线程是守护进程线程(我在Eclipse的调试视图中看到过)。但这是不可能的 - 我没有看到主线程,但看到守护线程!它是否与特定的Tomcat Web容器相关联,或者它可能是我的Web应用程序的问题? 谢谢。 或者它特定于Eclipse嵌入式Tomcat?
答案 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。想象一下在调试器代码本身中设置一个断点......我看到这可能会让事情变得混乱,因为你会锁定你的调试会话!
如果您没有使用调试器,请不要指望这种情况发生。