Consider the following:
public class Deadlock {
static class Friend{
private final String name;
public Friend (String name){
this.name = name;
}
public String getName(){
return this.name;
}
public synchronized void bow(Friend bower){
System.out.format("\n%S: %S has bowed to me!" , this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("\n%S: %S has bowed back to me!", this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alf = new Friend("Alf");
final Friend arian = new Friend("Arian");
// Thread 1
new Thread(new Runnable() {
public void run(){ alf.bow(arian);}}).start();
//Thread 2
new Thread(new Runnable() {
public void run(){ arian.bow(alf);}}).start();
}
}
The out put is
ALF: ARIAN has bowed to me!
ARIAN: ALF has bowed to me!
LOCK situation…..
When Thread 1 runs, it requires a lock on the object Friend. Immediately after that Thread 2 requires lock on the second object. Now the method bow is lock by thread 1 and thus prints “ALF: ARIAN has bowed to me!”. How comes Thread 2 enters bow and neither can enter * bowBack * ??
Regards B.
Bear in mind that
synchronizedmethods will always synchronise onthis.There are two objects and therefore two locks.
alf.bow()acquiresalfs lock andarian.bow()acquiresarians. But thenbowback()tries to acquire the other one, which is when the deadlock happens.If you want to synchronise on a shared lock object, you should do something like this:
Since
lockis in a static field, it means all instances ofFrienduse the same lock object, therefore there’s no chance of a deadlock.You can also synchronise on the class object
synchronized( Friend.class ) {...}, but synchronising on externally visible objects usually isn’t a good idea as there’s no guarantee that some other part of the code doesn’t steal the lock.