I am going through a Jakob Jenkov's concurrency tutorial and don't understand how a deadlock can occur in this piece of code:
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;
}
}
First thread 1 calls parent.addChild(child). Since addChild() is
synchronized thread 1 effectively locks the parent object for access
from other treads.
Then thread 2 calls child.setParent(parent). Since setParent() is
synchronized thread 2 effectively locks the child object for acces
from other threads.
The example states that
Here is an example of a TreeNode class that call synchronized methods in different instances:
So both threads entering synchronized
methods will sync on different objects, but then cause a deadlock because both have locked their own objects (parent, child) and then attempt to lock the "opposing" object (child, parent).
The example shows how locking things in the same order is important.