This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
On p94, Monkhouse's book about synchronization, here is the paragraph:
Consumer Thread 1:
Consumer Thread 2:
"By calling notifyAll after setting value, the producer can be sure that both consumers will check the current contents of the value variable, and one of them will be able to continue processing. If notify had been used instead of notifiyAll, it is possible that after setting value, the wrong thread may have been notified, and upon finding that the value variable did not contain the desire number, would have gone back to the Thread.State.WAITING state, meaning that neither consumer thread would be working!"
My interpretation about the above paragraph is that both consumer thread 1 and 2 may be waiting for the lock object concurrently.
But in my opinion, both consumer threads cannot be waiting for the lock concurrently. For example,
1. value = 0.0 initially.
2. consumer thread 1 holds the lock object, release the lock, and wait for the lock.
3. consumer thread 2 holds the lock object, the value>=0.5 condition fails, the syn block finishes and thread 2 release the lock.
4. producer thread holds the lock , set value to 0.1. If this thread use notify instead of notifyAll, consumer thread 1 will be notified because this thread is waiting. But consumer thread 2 will not be notified because it finishes it execution.
I don't understand this phrase "If notify had been used instead, it is possible that after setting value, the wrong thread may have been notified..." This phrase has an assumption that both consumer threads are waiting and notifyAll should be used. But when I look at this piece of code, ONLY one thread is waiting, not two threads are waiting. It's because value is either >=0.5 or <0.5.
In either case, one consumer thread should be waiting while another one should release the lock and finishes.
Can anyone help me to understand what the book say or verify my interpretation?
I agree with your analysis. I do prefer notifyAll() to notify() (in the extremely rare cases that I use wait/notify at all) for exactly the reasons mentioned in the text. However, in the case presented, I don't see any way both threads would be simultaneously waiting for lock.
As a challenge, you might try to come up with a simple example where notify() would have problems that would be solved by calling notifyAll(). You might even get it in the next edition of the book!