Originally posted by Sri Bala:
If saving CPU time is the only reason, I guess wait & notifyAll functionality could have been built within the language, transparent to the programmers. I guess there should be a stronger reason for giving it to the programmer.
Bala
Can you explain what you mean by saying that wait() and notifyAll() functionality could have been built within the language, transparent to programmers?
In fact wait() and notifyAll() are built within the language, that is why programmers can use them.
If they were transparent to programmers they would be of no use. Because when a thread must wait and when it must be notified is entirely determined by the PROGRAM LOGIC. Only the programmer can know the situation in which the thread must go into wait, and the situation when the waiting thread must be notified.
Take the classic producer-consumer thread example. In the simplest form, producer threads and consumer threads are running. The producer threads are regularly updating some value in a shared variable X, and the consumer thread are regularly retrieving the value stored in X.
At the first level- access to X must be synchronized- i.e. 2 threads- (2 consumers or 2 producers or 1 consumer+1producer) should not try to access simultaneously, because that may result in an indeterminate/inconsistent state.
At the next level - the program logic may require that producer should update only if the last update has been consumed, and the consumer should consume only if the update is new i.e. as yet unconsumed.
An inefficient way of implementing this logic would be to externally implement a busy loop where the threads are doing:-
while(!conditionSatified) {
acquire monitor on the shared object.
check if condition satisfied (update made/consumed)
if conditionSatisfied, produce/consume and break.
release monitor and continue loop if condition not satisfied.
}//end of while loop
An efficient way of doing the same thing is:-
acquire monitor on the shared object.
while(!conditionSatisfied) {
wait();
}
produce/consume;
notify();
release monitor
In the former inefficient method a busy loop is implementing to check if condition is satisfied. A busy loop by itself is loading the processor- and aggravating the load is the fact that lock/monitor has to be acquired in each loop. Thus Producer threads are uselessly competing for resources, even when the previous update has not yet been consumed, and similarly consumer threads are uselessly competing for resources even when no new update has been made.
Compare this with the efficient method. Here a thread acquires the monitor once- If condition is not satisfied, then it simply goes into wait() releasing the lock, confident that whenever another thread which does something which may change the condition conducively it would do notify()/notifyAll(). Of course after reviving from wait() the thread will again compete for a lock/monitor, but now it does so only when the situation has become promising (i.e. it is more likely to find the condition satisfied).
Thus in general terms a thread seeking a condition, will not continously/uselessly check for the condition, rather it will wait for a notification that the condition has arrived.
I think it is obvious by now, that only the programmer can know when to issue wait() and notify() because that is entirely determined by program logic. The wait() and notify() method are tools for efficient and consistent implementation of program logic. It would make no sense to hide those tools from the very person who can use them.