同步方法死锁

时间:2017-02-06 14:46:02

标签: java concurrency locking

我正在浏览a Jakob Jenkov's concurrency tutorial并且不明白这段代码中是如何发生死锁的:

  public class TreeNode {
  TreeNode parent   = null;  
  List     children = new ArrayList();

  public synchronized void addChild(TreeNode child){
    if(!this.children.contains(child)) {
      this.children.add(child);
      child.setParentOnly(this);
    }
  }

  public synchronized void addChildOnly(TreeNode child){
    if(!this.children.contains(child){
      this.children.add(child);
    }
  }

  public synchronized void setParent(TreeNode parent){
    this.parent = parent;
    parent.addChildOnly(this);
  }

  public synchronized void setParentOnly(TreeNode parent){
    this.parent = parent;
  }
}

作者的解释说:

  

第一个帖子1调用parent.addChild(child)。因为addChild()是   同步线程1有效地锁定父对象以进行访问   来自其他地方。

     

然后线程2调用child.setParent(parent)。因为setParent()是   同步线程2有效地锁定子对象以进行访问   来自其他主题。

由于所有4个方法都是“同步”的,所有这些方法都被“this”对象保护,所以恕我直言,第二个线程将不被允许获取锁定。还是我错了?

1 个答案:

答案 0 :(得分:2)

该示例说明了

  

以下是调用synchronized方法的TreeNode类的示例   在不同的情况下:

因此,进入synchronized方法的两个线程将同步不同的对象,但随后导致死锁,因为两者都锁定了自己的对象(父对象),然后尝试锁定“对立”对象(子对象,父对象) )。

该示例显示了以相同顺序锁定事物的重要性。