使用Java杀死正在运行的VM(JBoss Instance)上的线程?

时间:2011-01-21 19:16:31

标签: java jboss monitoring recovery

bug in a third party library导致我的JBoss实例上的工作线程中出现无限循环。你知道如何在不重新启动服务器的情况下杀死这个“卡住”的线程吗?我们希望能够从此恢复直到部署修复程序,最好不必重新启动。

我见过几个人mention using Thread.interrupt() - 如果我要编写自己的MBean代码,我怎样才能获得有问题的线程的句柄以便中断呢?

更新:无法使用任何这些方法解决。我确实遇到another thread about the same issue,其链接指向Thread.stop() is deprecated的原因。其他人asked a similar question的结果相似。似乎更复杂的容器应该提供这种健康机制,但我猜他们的手与JVM相关联。

4 个答案:

答案 0 :(得分:2)

我在第三方库中遇到了类似的错误(无限循环)。我最终自己应用了修复程序(等待来自第三方lib的人修复他们的混乱)然后我将修改后的 .class 放在我的 .war 中,确保它在伪造的 .class 之前加载(伪造的第三方 .jar 内的虚假)。

这不好但是有效,请看我的问题:

Order of class loading from a .war file

我的意思是:如果你必须等待负责第三方窃听lib的人修理他们的东西,你可能会等待非常很长时间。我们买不起。我们需要尽快修复。所以我们最终在他们的代码中应用补丁/黑客。

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

请注意,我已经十年没用过不推荐使用的Thread stop()了,我真的不想在上面的情况下使用它。

答案 1 :(得分:2)

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

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

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

识别线程后,您必须在其上调用stop()方法。除非正在运行的代码的实现实际上评估了线程的中断标志并且行为与您期望的一样,否则中断它将无济于事。并非stop()方法已被弃用,使用它可能会产生许多有趣的副作用。您可以在API文档中找到更多详细信息。

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

尝试尝试执行此类操作的jkillthread