我正在通过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种方法都是“同步的”,因此所有这些方法都由“此”对象保护,因此恕我直言,第二个线程将不允许获取锁。还是我错了?
最佳答案
该示例指出
这是一个调用同步方法的TreeNode类的示例
在不同的情况下:
因此,两个进入synchronized
方法的线程都将在不同的对象上同步,但是会导致死锁,因为这两个线程都锁定了自己的对象(父,子),然后尝试锁定“相反的”对象(子,父)。
该示例显示了以相同顺序锁定事物的重要性。