为什么java无法从死锁中恢复?

时间:2013-09-20 02:40:41

标签: java multithreading jvm

我正在阅读“Java Concurrency in Practice”一书,这里有关于死锁的内容。

  

JVM无法从死锁中恢复,只能摆脱死机   锁是重启服务器。它还提到JVM使用图形   搜索线程充当两个线程A之间的图形节点和边缘的位置   并且B被定义为线程A正在等待资源锁定   线程B持有该图表,如果有任何周期   这个图,然后有死锁

现在我的问题是,如果JVM知道存在死锁,那为什么不杀死一个线程并让其他线程继续?这背后是否有任何具体原因或我的问题本身是基于错误的结论?

请告诉我您对此的看法。在此先感谢!!!

2 个答案:

答案 0 :(得分:7)

  

现在我的问题是,如果JVM知道存在死锁,那为什么不杀死一个线程并让其他线程继续?这背后是否有任何具体原因或我的问题本身是基于错误的结论?

JVM如何决定杀死哪个线程?如果JVM在强制释放锁定时允许无效数据进入某种关键数据库会怎样?

JVM无法任意做出这些决定。它报告死锁但无法自动从中恢复。

在使用锁修改两个关键对象但两个线程以不同顺序锁定它们的任何情况下,您都可以看到此问题。数据库事务能够从这种死锁中恢复,因为它们旨在回滚表和索引,但Java同步锁没有隐式内存回滚功能。通过杀死一个线程并释放其锁,JVM将允许传播部分内存更新。

答案 1 :(得分:3)

杀死一个线程不会让对方明智地继续下去。事实上,杀死线程将是致命的。线程首先获得锁定的原因是在数据结构不一致的状态下将其他线程保留在某些数据结构之外。释放数据结构仍然处于不一致状态的锁将会严重污染进程上下文。

例如:

  1. 线程A锁定对象1。

  2. 线程B锁定对象2.

  3. 线程A将对象1置于不一致状态。

  4. 线程B将对象2置于不一致状态。

  5. 线程A对象2上的块。

  6. 对象1上的线程B阻塞。

  7. 现在两个线程如何进行?每个都在等待另一个线程将对象返回到一致状态。

    如果您不理解不一致状态的含义,这里有一个更清晰的例子。请考虑以下代码:

    1. 获取保护foobar的锁定。
    2. 如果foobar不是10,则开始第三次世界大战。(不用担心,程序员仔细确保foobar总是10,除非他确实有开始第三次世界大战。)
    3. 增量foo
    4. 获取其他锁。
    5. 减少bar
    6. 释放另一把锁。
    7. 释放保护foobar
    8. 的锁定

      如果你在第4步陷入僵局,你会怎么做?您无法释放保护foobar的锁定,因为运行此代码的下一个线程将启动第三次世界大战。显然,需要详细了解这个特定代码的作用,以解决僵局。