检测谁创建了线程(w. Eclipse)

2022-09-02 01:37:57

如何找出谁在 Java 中创建了线程?

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

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

那么,我该怎么办?我在 Eclipse 的 Debug View 中看到了这些线程。我看到它们的堆栈跟踪,但它们不包含任何有关其来源的提示。没有创建者的堆栈跟踪,没有可区分的类名,什么都没有。

有没有人知道如何解决这个问题?


答案 1

好吧,我能够自己解决(某种程度上)问题:我把一个断点放进去

Thread.start() 

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

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


答案 2

我虔诚地命名我的线程(使用Thread(Runnable,String)),否则它们最终会得到一个通用的,有点无用的名称。转储线程将突出显示正在运行的内容以及(因此)创建线程的内容。这并不能解决第三方线程创建问题,我很感激。

编辑:JavaSpecialist 时事通讯最近(2015 年 2 月)通过使用安全管理器解决了这个问题。有关更多详细信息,请参阅此处

更多:使用JavaSpecialist技术的几个细节:SecurityManager API包括在线程创建者的线程上调用的“checkAccess(newThreadBeingCreated)”。新线程已初始化其“名称”。因此,在这种方法中,您可以访问线程创建者的线程和新线程,并且可以记录/打印等。当我尝试这样做时,被监视的代码开始引发访问保护异常;我通过在AccessController.doPriviledged(new PrivilegedAction() { ... }下调用它来修复它,其中run()方法调用被监视的代码。


推荐