一尘不染

如何避免嵌套同步和由此产生的死锁

javascript

我需要在功能中锁定两个对象,当前代码看起来像这样;

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

synchronized(obj1){
  ...//blah
  synchronized(obj2){
     ...//blah
  }
}

如您所见,如果另一个线程使用obj1和两个相反的代码运行这段代码,则这是死锁的简单明了的配方。
有没有一种方法可以使用concurrency-utils锁来避免这种情况?

我当时正在考虑维护一个对象及其锁的地图,并验证它们是否可供使用,但是似乎无法提出一种可以预测锁顺序的干净方法。


阅读 361

收藏
2020-09-26

共1个答案

一尘不染

尽管您保留了锁定顺序,但是如果将obj1与obj2切换,则会遇到死锁。

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

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) {
               ...
            }
        }
    }
2020-09-26