java.lang.Thread
对象在run()
执行完成后保持活动的原因是什么?为了帮助理解这个问题,在ThreadGroup
完成时如何从run()
删除线程?
更新:保持活动的Thread
个对象与活动/活动的Thread
不同。当我问这个问题时,我正在调试Thread
对象泄漏(而不是Thread
泄漏)。对于基于GNU Classpath的JDK(Harmony应该是其中之一,对吗?),Thread
被添加到构造函数ThreadGroup
中的Thread.<init>
,并创建了Thread
但没有开始将被泄露(即,无论run()
完成,都保持活着)。在HotSpot中,Thread
中的ThreadGroup
已添加Thread.start()
,这似乎更有意义。换句话说,只有在启动时才会添加它,并且如果run()
没有挂起,则可以保证删除它。请注意,ThreadGroup
被视为GC根目录。
答案 0 :(得分:2)
您是在询问在run()
完成时线程会在什么情况下保持活动状态,或者java.lang.Thread
对象在什么情况下会保持不变?你的问题似乎要求后者,而且要记住的是,除了控制线程之外,Thread
对象也只是一个普通的'Java对象,受到与其他任何人相同的GC规则的约束。因此,即使其线程早已完成,Thread
实例也可以保留,如果某个其他线程持有它(线程是GC根)。
琐碎的例子
Thread t = new Thread();
t.start(); // will finish almost instantly
t.join();
// ...
在这个例子中,线程几乎在它开始时就完成了,当然在join()
返回时。但是,Thread
对象在GC中存活,直到t
引用超出范围或被设置为另一个对象。
查看代码,Thread通过私有方法ThreadGroup.remove(Thread)
从其ThreadGroup中删除,该方法由ThreadGroup.threadTerminated(Thread)
调用,Thread.exit()
是{{1}}调用的包私有方法,这是一个在JDK代码中没有调用的私有方法;它可能是由本机线程管理代码调用的。
答案 1 :(得分:0)
你的线程对象run
方法中的某些函数调用可能还没有返回,这意味着实际上run方法还没有完成!
我建议你在run
方法的最后一行打印类似&#34;完成&#34;然后监视主程序欠幅时间的输出。