可靠地停止无响应的线程 [英] Reliably stopping an unresponsive thread

查看:48
本文介绍了可靠地停止无响应的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何在 Java 中停止一个没有响应的线程,这样它就真的死了.

I'm wondering how to stop an unresponsive thread in Java, such that it's really dead.

首先,我很清楚Thread.stop() 已被弃用以及为什么不应该使用它;关于这个话题已经有很多很好的答案,参见.[1][2].所以,更准确地说,问题是,从技术上讲,是否真的有可能杀死一个代码不受我们控制但可能具有敌意且不响应中断的线程.

First of all, I'm well aware of Thread.stop() being deprecated and why it should not be used; there are already many excellent answers on this topic, cf. [1][2]. So, the question more precisely is, whether it's actually technically possibly to kill a thread which code is not controlled by us but possibly hostile and not responding to interrupts.

在最简单的情况下,一个恶意线程会运行 while(true);,但它也可能会耗尽内存或其他系统资源来造成更大的破坏.在该线程上调用 interrupt() 显然是无效的.改为调用 stop() 怎么样?

In the simplest case, a hostile thread would be running while(true);, but it could as well be using up memory or other system resources to do more damage. Calling interrupt() on that thread is obviously ineffective. What about calling stop() instead?

我在调试器中运行了这个,实际上,线程真的消失了.但这种方法可靠吗?可以为这种情况准备敌对线程;想想 try{run();}catch(ThreadDeath t){run();} 在那里它捕获当我们调用 stop() 时产生的 ThreadDeath) 并再次递归调用自身.

I have run this in a debugger and, in fact, the thread really disappears. But is this approach reliable? The hostile thread could be prepared for this case; think of try{run();}catch(ThreadDeath t){run();} where it catches the ThreadDeath that is produced when we call stop() and recursively calls itself again.

作为外部观察者,我们无法看到正在发生的事情;Thread.stop() 总是静默运行.最糟糕的是,通常的诊断不再起作用(在 Corretto 1.8.0_275 Windows x64 上调试时尝试过):Thread.getState() 总是返回 RUNNABLE成功杀死线程,同样适用于 Thread.isAlive()(始终为真).

As an outside observer, we cannot see what is going on; Thread.stop() always runs silently. Worst of all, the usual diagnostics won't work anymore (tried this while debugging on Corretto 1.8.0_275 Windows x64): Thread.getState() always returns RUNNABLE regardless of success in killing the thread, same goes for Thread.isAlive() (always true).

推荐答案

这可能是不可能的,至少不是在每种情况下都可靠.

It may not be possible, at least not reliably in every scenario.

如果我正确理解了该机制(并且存在一些不确定性),如果代码的执行方式在执行期间没有安全点(例如在计数循环中),则 JVM 不可能通知线程它应该停止(线程从不轮询中断).

IF I understand the mechanism correctly (and there is some uncertainty there), if the code executes in such a way that there are no safepoints during the execution (for example in counted loops), it is not possible for the JVM to signal to the thread that it should stop (the thread never polls for an interrupt).

在这种情况下,您需要杀死 JVM 进程,而不是线程.

In such a scenario, you need to kill the JVM process, rather than the thread.

一些额外的阅读:

JVM 时如何获取 Java 堆栈无法到达安全点

计数循环

这篇关于可靠地停止无响应的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆