-1

下面是一个具体的死锁案例:

有 2 个线程——T0 和 T1,以及 2 个资源——R0 和 R1。

T0 持有 R0 的锁并等待访问 R1 以释放 R0。T1 以相反的方式做同样的事情——持有 R1 并等待 R0。

我能想到的解决这个问题的方法:

经过一段时间的等待——这应该表示这个无限循环,Tx,x=0 或 1,将 Rx 的状态写入对象 Ox 并设置一个标志 Fx,它已完成更新 Rx。它还检查标志 F(1-x) 以查看它是否已设置——如果是,则从 O(1-x) 读取状态,并相应地继续并释放 Rx。在这种情况下,T0 和 T1 被优先考虑(Java 的线程类有方法优先处理线程(?),或者这可以通过类实例来实现 - 使用静态变量上的特定值创建的线程之一负责打破这个循环。)

如果 T(1-x) 在获取 Rx 时在 R(1-x) 上的进一步执行不会改变 R(1-x) 的状态,则此方法有效。

这种情况有什么问题?

有没有另一种/更好的方法来处理这个?

正如许多文章中指出的那样,我知道以有序的方式管理对资源的访问。

4

1 回答 1

1

这种情况有什么问题?

正常情况下,两个线程在尝试获取锁时都会被阻塞。(如果他们使用原始锁(即synchronized),那么就没有办法避免这种情况。)当线程被阻塞时,他们不能做任何事情来检测死锁。

或者,如果您使用类似的东西,Lock.tryLock(long time, TimeUnit unit)那么线程实际上并没有死锁。你所拥有的是一个活锁,线程tryLock在每次超时后盲目地重试。解决方法是不重试。如果 tryLock 调用超时,则将其视为错误。

有没有另一种/更好的方法来处理这个?

您可以使用ThreadMXBean来检测死锁线程。有关详细信息,请参阅https://stackoverflow.com/a/1102410/139985。显然,您必须在另一个线程上执行此操作……而不是在容易出现死锁的线程上!

(我通过谷歌搜索“Java死锁检测”找到了这个......并阅读了答案。)

于 2013-10-20T01:36:13.387 回答