7

第三方库中的错误导致我的 JBoss 实例上的工作线程中的无限循环。你知道在不重新启动服务器的情况下杀死这个“卡住”线程的方法吗?我们希望能够从中恢复,直到部署修复程序,最好不必重新启动。

我见过一些人提到使用 Thread.interrupt() - 如果我要编写自己的 MBean,我将如何获得相关线程的句柄以中断它?

更新:使用任何这些方法都无法解决。我确实遇到了另一个关于相同问题的线程,该线程与为什么不推荐使用 Thread.stop()有链接。有人问过类似的问题,结果也类似。似乎更复杂的容器应该提供这种健康机制,但我猜他们的双手与 JVM 捆绑在一起。

4

4 回答 4

2

我在 3rd 方库中有一个类似的错误(无限循环)。我最终自己应用了修复程序(同时等待来自 3rd 方库的人修复他们的烂摊子),然后我将修改后的.class放在我的.war中,确保它在假的.class之前加载(假的位于伪造的第 3 方.jar中)。

这不好,但它有效,请参阅我的问题:

从 .war 文件加载类的顺序

我的意思是:如果您必须等待负责第 3 方窃听库的人员来修复他们的东西,您可能会等待长时间。我们负担不起。我们需要尽快修复。所以我们最终对他们的代码应用了补丁/破解。

例如,您可以在无限循环中添加一个布尔检查,然后在您希望虚假线程“死亡”时强制循环退出。

请注意,十年以来我没有使用过不推荐使用的 Thread stop()并且我真的不想在上述情况下使用它。

于 2011-01-21T19:35:47.843 回答
2

我想最困难的部分是识别挂线。您没有提供有关它的信息,但也许您可以围绕线程名称或其当前堆栈跟踪构建一些规则。

如果您可以通过名称识别线程,我将通过获取我自己的线程组来获取 VM 中的所有线程Thread.currentThread().getThreadGroup(),然后通过调用getParent()线程组直到它返回来遍历线程组层次结构null。您现在拥有顶级线程组。enumerate(Thread[] list)您现在可以使用顶级线程组上的方法填充所有线程的预分配数组。

如果您仍然需要堆栈跟踪来识别线程,您还可以使用静态实用程序方法Map<Thread,StackTraceElement[]> Thread.getAllStackTraces()来获取所有线程。然而,计算堆栈跟踪非常昂贵,因此如果您实际上不需要它们,这可能不是最佳解决方案。

确定线程后,您必须调用stop()它的方法。中断它不会有帮助,除非正在运行的代码的实现实际上评估了线程的中断标志并按照您的预期运行。并不是说该stop()方法已被弃用,并且使用它可能会产生许多有趣的副作用。您可以在 API 文档中找到更多详细信息。

于 2011-01-21T19:36:50.813 回答
1

您可以使用不鼓励的 myThread.stop() 方法。但是很有可能线程仍然在那里被引用,所以你应该使用一些反射魔法从持有它的组件中删除对这个线程的所有引用。

如何找到线程?使用 Thread.getThreadGroup() 和 ThreadGroup.getThreadGroup() 向上到根 ThreadGroup(),然后使用 iterate() 函数遍历所有线程。

于 2011-01-21T19:34:55.987 回答
0

试试我的jkillthread,它试图做这样的事情。

于 2013-11-05T16:09:28.443 回答