如何避免嵌套同步和导致的死锁

Var*_*rde 2 java concurrency locks

我需要在一个功能中锁定两个对象,并且当前代码如下所示;

Object obj1  = ...//get from somewhere
Object obj2 = ...//get from somewhere

synchronized(obj1){
  ...//blah
  synchronized(obj2){
     ...//blah
  }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,如果另一个线程使用obj1运行这段代码并且两个反转,这是一个简单而直接的死锁配方.
有没有办法使用concurrency-utils锁来避免这种情况?

我正在考虑维护一个物体及其锁的地图,并验证它们是否可以使用,但似乎无法想出一种可以预测锁定顺序的清洁方式.

Ovi*_*pas 6

虽然你保留了锁定顺序,但如果使用obj2切换obj1,你将遇到死锁.

您必须寻找另一种解决方案以避免这种情况:锁定顺序+可选的打破锁定

int fromHash = System.identityHashCode(obj1);
int toHash = System.identityHashCode(obj2);

if (fromHash < toHash) {
    synchronized (obj1) {
        synchronized (obj2) {
               ........
        }
    }
} else if (fromHash > toHash) {
    synchronized (obj2) {
        synchronized (obj1) {
            ........
        }
    }
} else {
    synchronized (TIE_LOCK) {
        synchronized (fromAcct) {
            synchronized (toAcct) {
               ...
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)