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.
There are four methods of handling deadlocks - deadlock avoidance, deadlock prevention, deadline detection and recovery and deadlock ignorance.
Deadlock can be prevented by eliminating any of the four necessary conditions, which are mutual exclusion, hold and wait, no preemption, and circular wait. Mutual exclusion, hold and wait and no preemption cannot be violated practically.
A deadlock occurs when 2 processes are competing for exclusive access to a resource but is unable to obtain exclusive access to it because the other process is preventing it. This results in a standoff where neither process can proceed. The only way out of a deadlock is for one of the processes to be terminated.
Bear in mind that synchronized
methods will always synchronise on this
.
There are two objects and therefore two locks. alf.bow()
acquires alf
s lock and arian.bow()
acquires arian
s. But then bowback()
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:
class Friend {
private static final Object lock = new Object();
public void bow(...) {
synchronized( lock ) {
...
}
}
public void bowback(...) {
synchronized( lock ) {
...
}
}
}
Since lock
is in a static field, it means all instances of Friend
use 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With