你会解释locking顺序吗?

我了解到,我应该解锁相反的顺序来locking订单。 例如。

A.lock(); B.lock(); B.unlock(); A.unlock(); 

但是,如果我这样做会发生什么:

 A.lock(); B.lock(); A.unlock(); B.unlock(); 

我试图做一个死锁的情况,但如果我总是先lockingA然后B,那么我不知道会发生什么样的死锁。 你能帮我吗?

lockingsorting意味着你通过以固定顺序获得锁来防止死锁,并且在你开始解锁之后不要再获取锁。

我不认为解锁的顺序在这里有什么区别(事实上,尽快释放locking应该是有益的,即使不按顺序)

在简单的情况下,以相反的顺序解锁并不是必要的,以避免死锁。

但是 ,随着代码变得更加复杂,以相反的顺序解锁可以帮助您保持正确的locking顺序。

考虑:

 A.lock(); B.lock(); Foo(); A.unlock(); Bar(); B.unlock(); 

如果Bar()尝试重新获取A,那么实际上已经破坏了你的locking顺序。 你拿着B,然后试着拿A,现在可能死锁。

如果你以相反的顺序解锁(如果你使用RAII,这是非常自然的):

 A.lock(); B.lock(); Foo(); B.unlock(); Bar(); A.unlock(); 

那么Bar()试图取锁就没有关系,因为locking顺序将被保留。

你的榜样不会自己陷入僵局。 以相反顺序解锁并不重要,它以一致的顺序locking。 即使解锁顺序相反,这也会导致死锁

 Thread 1 A.lock(); B.lock(); B.unlock(); A.unlock(); Thread 2 B.lock(); A.lock(); A.unlock(); B.unlock(); 

我不认为这里会发生死锁。 一般死锁概念是一个线程等待某个资源被其他线程locking,而另一个线程则需要第一个线程locking的资源完成并释放第一个需要的资源。

进一步阅读

解锁的顺序不会影响你的系统发生死锁的容易程度,但有一个原因可以考虑解锁的顺序:

为了避免死锁,您必须确保您的locking/解锁配对,因为您永远不会错过解锁。 作为一种风格的方法,通过明显地具有负责特殊locking的代码块,更容易以视觉方式识别locking和解锁是成对的。 最终的效果是,正如你所描述的那样,明显正确的代码可能会采取和释放锁。

对于Java,如果使用synchronized关键字进行locking,则解锁顺序相反。 无法以不同的顺序解锁使用synchronized关键字。

 synchronized(a) { synchronized(b) { // statements } } 
  > lock(B) > ---------- lock(C) > ---------- lock(B) >>>> would block here > ---------- release(B) > ---------- release(C) > lock(C) >>>>>> would block here > release(B) > release(C) 

他们的答案很好,如果执行无序的locking和释放,另一种情况可能会发生死锁。 一句话, 无序释放和locking打破了我们用来devise我们的共享资源pipe理和关键区域的假设。