有没有办法中断,终止或以其他方式解除(释放同步锁)一个死锁的Java线程,允许其他线程继续?

问题描述 投票:1回答:2

我有一个长期运行的进程,由于一个错误,一个琐碎/可消耗的线程被一个线程死锁,我想继续,以便它可以执行一些难以以另一种方式重现的最终报告。

当然,为将来的运行修复bug是正确的最终解决方案。当然,任何这种强制中断/终止/停止任何线程本质上都是不安全的,并且可能导致其他不可预测的不一致。 (我熟悉所有标准警告及其原因。)

但仍然,因为唯一的选择是杀死JVM进程并经历一个更冗长的过程,这会导致最终报告不完整,凌乱/弃用/危险/冒险/一次性技术正是我想要的试试。

JVM是Sun的1.6.0_16 64位Ubuntu,可消耗线程正在等待锁定对象监视器。

指向精确线程的OS信号是否可以在可消耗线程中创建InterruptedException?

可以附加gdb,直接篡改JVM数据或调用JVM程序允许强制释放由可消耗线程持有的对象监视器吗?

来自另一个线程的Thread.interrupt()会从等待锁定的帧中生成InterruptedException吗? (通过一些努力,我可以将一个任意的beanshell脚本注入到正在运行的系统中。)

可以通过JMX或任何其他远程注入方法发送弃用的Thread.stop()吗?

任何想法都赞赏,越“危险”,越好!并且,如果您的建议在类似情况下的个人经验中起作用,那就最好了!

java synchronization gdb deadlock interrupted-exception
2个回答
2
投票

指向精确线程的OS信号是否可以在消耗线程中创建InterruptedException

没有。

可以附加gdb,直接篡改JVM数据或调用JVM程序允许强制释放由可消耗线程持有的对象监视器吗?

理论上是的。在实践中,您需要深入了解JVM的内部,才有可能取得成功。实际上,没有。

来自另一个线程的Thread.interrupt()会从等待锁定的帧中生成InterruptedException吗? (通过一些努力,我可以将一个任意的beanshell脚本注入到正在运行的系统中。)

理论上是的。在实践中,beanshell脚本需要找到要中断的线程的Thread对象。这可能涉及遍历ThreadGroup对象的树等。另一个问题是被中断的线程是否会正常运行。例如,很多人写他们的等待/通知代码来捕获/忽略InterruptedException并重试。如果你已经这样做了,中断可能不会有任何好处。

可以通过JMX或任何其他远程注入方法发送弃用的Thread.stop()吗?

如果你可以调用Thread.interrupt(),你可以使用相同的方法来调用Thread.stop()。通常情况下,我会说不要这样做。但在这种情况下,可能值得一试。

但是所有这一切的真正教训是,可能需要数天或数周才能产生答案的应用程序应该实施检查点/恢复机制来处理这种可能性,以及电源故障,硬件故障,机器重启,等等


0
投票

算了吧。在最好的情况下,您可以通过一些监视程序计时器检测死锁,忽略被卡住的线程,并创建新线程以继续工作。不太满意。您无法解锁所涉及的锁,并且有两个锁(或更多)。你不能让“消耗性”线程释放它所持有的锁。

有一种相当简单的方法可以检测潜在的死锁:将一个级别从1向上分配给每个锁。强制执行规则“在持有锁定时,线程必须只获取较低级别的锁”。如果您发现违反规则,请修改编号。如果它无法修复,那么你有一个潜在的僵局,可能运气不好会变成一个真正的僵局。改变你的代码。

© www.soinside.com 2019 - 2024. All rights reserved.