Reputation: 99526
From Programming Language Pragmatics, by Scott
While maintaining exclusion on outer monitor(s) when waiting in an inner one may lead to deadlock with a signaling thread, releasing those outer monitors may lead to similar (if a bit more subtle) deadlocks. When a waiting thread awakens it must reacquire exclusion on both inner and outer monitors. The innermost monitor is of course available, because the matching signal happened there, but there is in general no way to ensure that unrelated threads will not be busy in the outer monitor(s). Moreover one of those threads may need access to the inner monitor in order to complete its work and release the outer monitor(s). If we insist that the awakened thread be the first to run in the inner monitor after the signal, then deadlock will result. One way to avoid this problem is to arrange for mutual exclusion across all the monitors of a program. This solution severely limits concurrency in multiprocessor implementations, but may be acceptable on a uniprocessor.
How do the two cases highlighted by me in bold lead to deadlocks?
I have trouble to understand the text, especially for the second case. Would appreciate any help to explain them in a clearer way.
Thanks.
Upvotes: 0
Views: 1074
Reputation: 999
See the case,the code like:
new Thread(new Runnable() { //thread 1
@Override
public void run() {
synchronized (outer){
synchronized (inner){
try {
outer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
Thread.sleep(1000);
new Thread(new Runnable() { //thread2
@Override
public void run() {
synchronized (outer){
System.out.println("get outer");
synchronized (inner){
System.out.println("get inner");
}
}
}
}).start();
The thread1 will release the outer monitor,but still hold the inner monitor,when the thread2 run,it will acquire the outer monitor successfully,but can't acquire the inner monitor.This will occurs deadlock.
And see the other case:
change the outer.wait();
to inner.wait();
,this still occur deadlock.
Because the thread1 will hold the outer monitor,and the thread2
will not acquire that.
Upvotes: 1
Reputation: 511
maintaining exclusion on outer monitor(s) when waiting in an inner one When a process is waiting on an inner monitor it can keep the exclusion on all outer monitors it is maintaining. This may lead to a deadlock when another process wants access to one of the outer monitors, but has access to the inner one on it's own, creating a deadlock.
releasing those outer monitors: Imagine a thread waiting for an inner monitor and releasing his outers to ensure that some others may gain access to them while the process is waiting. Now when the thread awakens (=the inner monitor is free to access it again),it needs to get the outer monitor which it released while waiting. And here comes the problem with this one: " but there is in general no way to ensure that unrelated threads will not be busy in the outer monitor(s)"
Upvotes: 1