Hi,
notifyAll() definitely has the obvious overhead to go through all threads in the object's wait list vs. just picking one in notify(). It is a O(n) vs. O(1) issue.
But I am thinking if people are actually referring to another potentially worse overhead when we say notifyAll() is bad.
Typical case:
1: public synchronized int get() {
2: while (available == false) {
3: try {
4: //wait for Producer to put value
5: wait();
6: } catch (InterruptedException e) { }
7: }
8: available = false;
9: return contents;
10: }
public synchronized void put(int value) {
contents = value;
available = true;
//notify Consumer that value has been set
notifyAll();
}
When there are multiple threads waiting on the 'this' object, notifyAll() wakes up all of them, but only one winning
thread can grab the lock on the 'this' object and execute line 6-10.
For the rest:
1) Got woken up
2) Go back to wait state for grabbing the lock to enter line 6
3) When winning thread is done with line 10, grab lock, loop back to line3.
4) Release lock and back to where it was before the notifyAll() was invoked.
This sounds bad to me, each losing thread will do this grab lock, release lock just to get back to where it was. And if line 6-10 takes a long time, it is very likely that there will be a good number of context switches incurred (due to losing thread gets woken up, but need to go back to wait state again realizing line 6 still cannot be entered).
What do you guys think? It feels to me that the latter drawback is the real problem.
Thanks
[ October 21, 2005: Message edited by: Victor Ho ]