线程到达结束但未被删除

时间:2009-12-15 10:59:47

标签: java multithreading

我创建了一堆线程来进行一些处理:

new Thread("upd-" + id){
    @Override
    public void run(){
        try{
            doSomething();
        }
        catch (Throwable e){
            LOG.error("error", e);
        }
        finally{
            LOG.debug("thread death");
        }
    }
}.start();

我知道我应该使用threadPool,但在更改之前我需要了解以下问题:

我正在使用eclipse的调试器并查看调试窗格中列出活动线程的线程。

其中许多都按照您的预期完成,并从调试窗格中删除,但是有些似乎仍保留在活动线程列表中,即使日志显示这些的“线程死亡”条目。

当我尝试调试这些线程时,它们要么不暂停调试或显示错误对话框:“检索线程的堆栈帧时发生超时:upd -...”。

doSomething()调用中有一些同步,但我很确定它没问题,因为正在调用“线程死亡”日志,我假设这些线程在该方法中没有死锁。

我没有做任何Thread.join(),但我确实称之为第三方API,但他们怀疑他们是否做过。

有人能想到这些线程挥之不去的另一个原因吗?

感谢。

编辑:

我创建了这个测试以检查垃圾收集理论:

Thread thread = new Thread("!!!!!!!!!!!!!!!!")
{
    @Override
    public void run()
    {
        System.out.println("running");
        ThreadUs.sleepQuiet(5000);
        System.out.println("finished"); // <-- thread removed from list here
    }
};
thread.start();
ThreadUs.sleepQuiet(10000);
System.out.println(thread.isAlive()); // <-- thread already removed from list but hasn't been GC'd
ThreadUs.sleepQuiet(10000);

这证明它与垃圾收集无关,因为eclipse一旦完成就从线程列表中删除线程,并且不等待对象被取消引用/ GC'd。

2 个答案:

答案 0 :(得分:2)

可能是Thread对象本身还没有被垃圾收集,这就是你所看到的吗?或许Eclipse认为你可能想要来查看线程(检查它的最终状态或其他)并保持它自己。

当你没有调试时,你有没有证据表明这是一个问题?

答案 1 :(得分:0)

我把它放到了调试器怪异的地方。