2012-01-12 53 views
1

我在Eclipse嵌入式Tomcat中运行多线程Web应用程序。有些线程是守护进程,有些则不是。 后,我已经运行:在主线程退出后,java中是否可以继续守护进程线程?

shutdown.bat 

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

回答

3

是的。所有非守护线程完成后,程序将退出。如果main启动一个正在运行的非守护进程线程,让线程调用“main”退出不会执行任何操作。

+0

但问题可能是关于我在调试器中看到的情况 - 我没有看到主线程,但可以看到守护进程(也称为非守护进程)。线程总数在接近50%时下降。 – user710818 2012-01-12 10:27:27

+0

即使一个非守护线程(可能由一个没有将该线程标记为守护进程的库启动)也会使程序继续运行。 – 2012-01-12 10:31:03

+0

我的问题(请阅读标题)关于与docs的矛盾 - 在那里说守护线程不能没有主线程存在。 – user710818 2012-01-12 10:33:19

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 
1

您正在运行一个调试器,这基本上意味着JVM终止不会像预期的那样运行。

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

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

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

相关问题