2009-08-04 63 views
21

如何找出谁在Java中创建线程?检测谁创建了线程(w。Eclipse)

想象一下:在一个复杂的插件环境中,使用〜30 第三方 JAR。你启动它,运行大量代码,做一些计算并最终调用shutdown()。

这个生命周期通常工作正常,除了每次运行一些(非守护进程)线程仍然悬而未决。如果每次关机都是最后一次关机,这就不成问题,我可以简单地在这种情况下运行System.exit()。但是,这个循环可能会运行多次,并且每次都会产生更多垃圾。

那么,我该怎么办?我在Eclipse的Debug View中看到线程。我看到他们的堆栈痕迹,但他们不包含任何有关他们的起源的暗示。没有创建者的堆栈跟踪,没有可区分的类名,什么也没有。

有没有人有一个想法如何解决这个问题?

+0

我想你应该能够在继承的acc字段中看到代码源。 – 2009-08-06 08:01:46

+0

相关http://stackoverflow.com/questions/9874641/tracking-java-thread-creation-and-lifetime – 2016-11-11 09:41:52

回答

10

我虔诚地命名我的线程(例如使用Thread(Runnable, String)),否则它们最终会产生一个通用而且无用的名称。转储线程将突出显示正在运行的内容以及(因此)创建它们的内容。这并不能解决第三方线程的创建,我很欣赏。

编辑:JavaSpecialist通讯最近通过使用安全管理器解决了这个问题(2015年2月)。请参阅here for more details

更多信息:有关使用JavaSpecialist技术的一些细节:SecurityManager API包括在线程创建者线程上调用的“checkAccess(newThreadBeingCreated)”。新线程已经初始化其“名称”。所以在这种方法中,你可以访问线程创建者的线程和新的线程,并且可以记录/打印等。当我尝试这个时,被监视的代码开始抛出访问保护异常;我通过在AccessController.doPriviledged(新的PrivilegedAction(){...}中调用它来解决这个问题,其中run()方法称为被监视的代码

0

不幸的是它没有在Eclipse中看到所有阻塞线程,但是它们的堆栈轨迹仅仅反映了它们的内部状态,并且(显然)没有公开关于它们创建位置的信息,并且从对象内部看(使用Variables视图),我无法得到任何进一步的提示。

+0

“不幸的是,它不” - 什么是“它”,它不是什么? – 2009-08-04 13:29:55

1

在调试Eclipse应用程序时,可以通过在调试视图中单击org.eclipse.equinox.launcher.Main字段来停止所有线程。

然后从那里为每个线程请参阅堆栈跟踪并进入最后的运行方法。

有时候这可以帮助,有时候不会。

正如Brian说,这是因为它能够轻松识别“谁创造了他们”唯一的办法了良好的实践来命名线程

13

好吧,我是能够解决(在某种程度上)对我自己的问题:我把一个断点放入

Thread.start() 

并手动逐步通过每个调用。通过这种方式,我发现很快,Class.forName()初始化了许多静态代码,它们反过来创建了这些神秘的线程。

虽然我能解决我的问题,但我仍然认为更一般的任务仍然没有得到解决。