简体   繁体   English

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

[英]Kill a stuck thread on a running VM (JBoss Instance) in Java?

A bug in a third party library is causing an infinite loop in a worker thread on a JBoss instance of mine. 第三方库中的错误导致我的JBoss实例上的工作线程中出现无限循环。 Do you know of a way to kill this "stuck" thread without restarting the server? 你知道如何在不重新启动服务器的情况下杀死这个“卡住”的线程吗? We'd like to be able to recover from this until a fix is deployed, preferably without having to restart. 我们希望能够从此恢复直到部署修复程序,最好不必重新启动。

I've seen a few people mention using Thread.interrupt() - if I were to code my own MBean, how would I get a handle to the thread in question in order to interrupt it? 我见过一些人提到使用Thread.interrupt() - 如果我要编写自己的MBean代码,为了打断它,我怎样才能获得有问题的线程的句柄?

Update: Wasn't able to solve using any of these methods. 更新:无法使用任何这些方法解决。 I did come across another thread about the same issue that had a link to why Thread.stop() is deprecated . 我确实遇到了另一个关于同一问题的线程,该问题有一个链接到为什么不推荐使用Thread.stop() Someone else has asked a similar question with similar results. 其他人也提出了类似的问题并得到了类似的结果。 It seems like more sophisticated containers should provide this kind of health mechanism, but I guess their hands are tied w/r/t the JVM. 似乎更复杂的容器应该提供这种健康机制,但我猜他们的手与JVM相关联。

I had a similar bug (infinite loop) in a 3rd party lib. 我在第三方库中遇到了类似的错误(无限循环)。 I ended up applying the fix myself (while waiting for the people from the 3rd party lib to fix their mess) and then I placed the modified .class in my .war , making sure it is loaded before the bogus .class (the bogus one being inside the bogus 3rd party .jar ). 我最终自己应用了修复程序(等待来自第三方库的人修复他们的混乱)然后我将修改后的.class放在我的.war中 ,确保它在伪造之前加载.class (伪造的在伪造的第三方.jar )。

It is not nice but it works, see my question here: 这不好但是有效,请看我的问题:

Order of class loading from a .war file 从.war文件加载类的顺序

What I mean is this: if you have to wait for the people responsible for the 3rd party bugged lib to fix their stuff, you can potentially be waiting a very long time. 我的意思是:如果你必须等待负责第三方窃听lib的人修理他们的东西,你可能会等待长时间。 We couldn't afford that. 我们买不起。 We needed a fix ASAP. 我们需要尽快修复。 So we ended up applying a patch/hack to their code. 所以我们最终在他们的代码中应用补丁/黑客。

You could for example add a boolean check inside the infinite loop and then forcing the loop to exit when you want the bogus thread to "die". 例如,您可以在无限循环内添加布尔检查,然后在您希望虚假线程“死”时强制循环退出。

Note that I haven't used the deprecated Thread stop() since ten years and I really didn't want to use it in the above case. 请注意,我已经十年没用过不推荐使用的Thread stop()了 ,我真的不想在上面的例子中使用它。

I suppose the most difficult part is to identify the hanging thread. 我想最困难的部分是识别悬挂线程。 You provide no info about it, but perhaps you can build some rules around the thread's name or its current stack trace. 您没有提供有关它的信息,但也许您可以围绕线程的名称或其当前堆栈跟踪构建一些规则。

If you can identify the thread by its name, I would get all threads in the VM by getting my own thread group with Thread.currentThread().getThreadGroup() , then walk up the thread group hierarchy by calling getParent() on the thread group until it returns null . 如果你可以通过它的名字来识别线程,我将通过使用Thread.currentThread().getThreadGroup()获取我自己的线程组来获取VM中的所有线程,然后通过在线程上调用getParent()来向上线程组层次结构组,直到它返回null You now have the top level thread group. 您现在拥有顶级线程组。 You can now fill a preallocated array with all threads using the enumerate(Thread[] list) method on the top level thread group. 您现在可以使用顶级线程组上的enumerate(Thread[] list)方法使用所有线程填充预分配的数组。

If you need the stack traces anyway to identify the thread, you can also use the static utility method Map<Thread,StackTraceElement[]> Thread.getAllStackTraces() to get all threads. 如果您还需要堆栈跟踪来识别线程,您还可以使用静态实用程序方法Map<Thread,StackTraceElement[]> Thread.getAllStackTraces()来获取所有线程。 Computing the stack traces is however quite expensive, so this might not be the best solution if you don't actually need them. 然而,计算堆栈跟踪非常昂贵,因此如果您实际上不需要它们,这可能不是最佳解决方案。

After identifying the thread you must call the stop() method on it. 识别线程后,必须在其上调用stop()方法。 Interrupting it won't help, unless the implementation of the running code actually evaluates the thread's interrupted flag and behaves as you expect it to. 除非正在运行的代码的实现实际上评估了线程的中断标志并且行为与您期望的一样,否则中断它将无济于事。 Not that the stop() method is deprecated and that using it may have many funny side effects. 并不是说不推荐使用stop()方法,使用它可能会产生许多有趣的副作用。 You can find more details in the API documentation. 您可以在API文档中找到更多详细信息。

You could use the discouraged myThread.stop() method. 您可以使用不鼓励的myThread.stop()方法。 But then it is very likely the Thread is still referenced there, so you should use some reflection magic to remove all references to this thread from the components holding it. 但是后来很可能仍然在那里引用了Thread,所以你应该使用一些反射魔法从包含它的组件中删除对该线程的所有引用。

How to find the Thread? 如何找到线程? Use Thread.getThreadGroup() and ThreadGroup.getThreadGroup() to go up to the root ThreadGroup(), and then use the iterate() functions to go through all threads. 使用Thread.getThreadGroup()和ThreadGroup.getThreadGroup()转到根ThreadGroup(),然后使用iterate()函数遍历所有线程。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM