Reputation: 2059
I have a simple code as below to test the deadlock
public class ClassB {
public synchronized void fooB(Classs A) throws InterruptedException{
System.out.print("Thread : " + Thread.currentThread().getName()+ " entered to fooB \n");
Thread.sleep(1000);
System.out.print("ClassB locked the fooA \n");
A.lastA();
}
public synchronized void lastB(){
System.out.print("I am lastB \n");
}
}
And Also I have another class called ClassA:
public class ClassA {
public synchronized void fooA(ClassB B) throws InterruptedException{
System.out.print("Thread : " + Thread.currentThread().getName()+ " entered to fooA \n");
Thread.sleep(1000);
System.out.print("ClassA locked the fooB \n");
B.lastB();
}
public synchronized void lastA(){
System.out.print("I am lastA \n");
}
}
So, now I have another code that calls these classes and causes a deadlock as below :
public class DeadLockTest implements Runnable {
ClassA ca=new ClassA();
ClassB cb=new ClassB();
public DeadLockTest() throws InterruptedException{
new Thread(this).start();
ca.fooA(cb);
}
public void run() {
try {
cb.fooB(ca);
} catch (InterruptedException ex) { ....
}
}
}
As you can see the first thread locks fooB using ca.fooA(cb) and the second thread locks fooA using cb.fooB(ca) and Nobody has any lock over lastA and lastB methods. It means these methods are supposed to be available but they are not available. Why? The threads have just lock over fooA and fooB. So, why for example the first thread can't use lastB() and the second one has not access to lastA() while there is no lock on these two methods?
Upvotes: 5
Views: 142
Reputation: 1445
This looks fairly straight forward. It's a typical circular shared resource scenario. A needs B to continue and B needs A to continue.
Locks:
Thread 1 -> ClassB -> ClassA
Thread Main -> ClassA -> ClassB
Processing Order:
Upvotes: 3
Reputation: 9559
You are synchronizing the methods, so the lock object is the object in each case (ca and cb).
When the thread calls cb.fooB(ca)
it grabs the lock object cb.
Then the main thread calls ca.fooA(cb)
and so grabs the lock object ca.
But, the fooA
method calls cb.lastB()
in the main thread, and this method is anso synchronized, so the main thread tries to grab the lock cb, only to find that the other thread has the lock already, so it must wait.
In the meantime, the other thread has called cb.fooB(ca)
which in turn calls ca.lastA()
, so tries to grab the lock on ca, only to find that the main thread already has the lock, so it too must wait.
Result: each thread has a lock the other needs to proceed, so they wait for each other. Deadlock.
Upvotes: 0
Reputation: 7396
When used on a method, the synchronized
keyword implicitly locks on this
-- well, on the monitor associated with this
. Objects have monitors; methods do not. So the monitor being used for fooA()
is the same monitor being used on lastA()
. That's why you have the deadlock.
Please read up on synchronized
before you go any further...
Upvotes: 11