我正在浏览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”对象保护,所以恕我直言,第二个线程将不被允许获取锁定。还是我错了?
答案 0 :(得分:2)
该示例说明了
以下是调用synchronized方法的TreeNode类的示例 在不同的情况下:
因此,进入synchronized
方法的两个线程将同步不同的对象,但随后导致死锁,因为两者都锁定了自己的对象(父对象),然后尝试锁定“对立”对象(子对象,父对象) )。
该示例显示了以相同顺序锁定事物的重要性。