如何避免嵌套同步和由此产生的死锁 [英] How to avoid Nested synchronization and the resulting deadlock

查看:609
本文介绍了如何避免嵌套同步和由此产生的死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  Object obj1 = ... //从某处获取
对象obj2 = ... //从某处获取

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

正如你可以看到,如果另一个线程使用obj1和两个反转运行这段代码,那么这是死锁的简单和直接的方法。

有没有办法避免这种情况使用concurrency-utils锁?



我在考虑维护一个对象和他们的锁的地图,并验证他们是否可以采取,但似乎不提出一个干净的方式,将预测锁定顺序。

解决方案

虽然保留锁定顺序,但如果obj1与obj2切换, p>

您必须寻找另一个解决方案来避免这种情况:lock ordering + optional tie breaking lock

  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){
.. 。
}
}
}


I need to lock two objects in a functionality and the current code looke like this;

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

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

As you can see this is a plain and straight recipe for deadlocks if another thread runs this piece of code with obj1 and two reversed.
Is there a way to avoid this situation using concurrency-utils locks?

I was contemplating maintaining a map of objects and their locks and verifying if they were available to take, but can't seem to come up with a clean way which will predict the lock order.

解决方案

Although you preserve locking order, if obj1 is switched with obj2 you'll run into deadlock.

You must look for another solution to avoid this cases: lock ordering + optional tie breaking lock

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

这篇关于如何避免嵌套同步和由此产生的死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆