为什么java无法从死锁中恢复?
我正在阅读Java Concurrency in Practice一书,这里有关于死锁的内容。
JVM无法从死锁中恢复,只有摆脱死锁的方法是重启服务器。 它还提到JVM使用图搜索,其中Thread充当图节点,并且两个线程A和B之间的边缘被定义为线程A正在等待线程B已经拥有的资源上的锁定。该图是有针对性的,如果有任何周期这个图,然后有死锁
现在我的问题是,如果JVM知道存在死锁,那为什么不杀死一个线程并让其他线程继续? 这背后是否有任何具体原因或我的问题本身是基于错误的结论?
请告诉我您对此的看法。 提前致谢!!!
现在我的问题是,如果JVM知道存在死锁,那为什么不杀死一个线程并让其他线程继续? 这背后是否有任何具体原因或我的问题本身是基于错误的结论?
JVM如何决定杀死哪个线程? 如果JVM在强制释放锁定时允许无效数据进入某种关键数据库,该怎么办?
JVM无法任意做出这些决定。 它报告死锁但无法自动从中恢复。
在使用锁修改两个关键对象但两个线程以不同顺序锁定它们的任何情况下,您都可以看到此问题。 数据库事务能够从这种死锁中恢复,因为它们旨在回滚表和索引,但Java同步锁没有隐式内存回滚function。 通过杀死一个线程并释放其锁,JVM将允许传播部分内存更新。
杀死一个线程不会让对方明智地继续下去。 事实上,杀死线程将是致命的。 线程首先获取锁定的原因是在数据结构不一致的状态下将其他线程保留在某些数据结构之外。 释放数据结构仍然处于不一致状态的锁将会严重污染进程上下文。
例如:
-
线程A锁定对象1。
-
线程B锁定对象2。
-
线程A将对象1置于不一致状态。
-
线程B将对象2置于不一致状态。
-
线程A对象2上的块。
-
线程B阻塞对象1。
现在两个线程怎么办? 每个都在等待另一个线程将对象返回到一致状态。
这是一个更清晰的例子,以防你不明白我的意思是一个不一致的状态。 考虑以下代码:
- 获取保护
foo
和bar
的锁。 - 如果
foo
plusbar
不是10,那就开始第三次世界大战。(不用担心,程序员小心翼翼地确保foo
加上bar
总是10,除非他真的要开始第三次世界大战。) - 增量
foo
。 - 获得一些其他锁。
- 减少
bar
- 释放另一把锁。
- 释放保护
foo
和bar
的锁。
如果你在第4步陷入僵局,你会怎么做? 你无法释放保护foo
和bar
的锁,因为运行此代码的下一个线程将启动第三次世界大战。 显然,需要详细了解这个特定代码的作用,以解决僵局。