This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I pasted the code below. That is commented enough.
Clear about wait(). When comes here it jumps to another block. That part i am oaky.
My doubt is Why we are using notify and notifyAll(). If you remove these two from below code, it works fine.
There is a possibility of spurious wakeups when a thread ends waiting without any visible reason. And in your case it is almost definitely a "spurious wakeups" because you wait on a thread object. There may be JVM notifications on a thread lifetime events. For example, thread termination may wake up all other threads waiting on it (similar to a notifyAll() call).
It is also not a very good idea to extends Thread at all. Usually your classes are not threads but a some other logical unit. Common use case for threads is to provide it a runnable as an argument:
If you change Calculator to implement Runnable and run it using new thread, you should feel the difference.
One side-note. You may need to add some delay in a calculator (Thread.sleep will count) to see difference between notify and notifyAll. On my computer only one Reader is notified if there is no additional delay in Calculator even when I use notifyAll. It's all is matter of timing. Threads are launched almost simultaneously so they may arrive to a synchronized block in a different order. Even with the delay there is no guaranteed sequence (and guaranteed order will require much more code) but most likely you will got all readers notified.
Maxim Karvonen wrote:There is a possibility of spurious wakeups when a thread ends waiting without any visible reason. And in your case it is almost definitely a "spurious wakeups" because you wait on a thread object. There may be JVM notifications on a thread lifetime events. For example, thread termination may wake up all other threads waiting on it (similar to a notifyAll() call).
First, the reason Java mentions "spurious wakeups" in the specification, is because the threading system sits on top of the native threading systems. And today, most threading systems has issues with spurious wakeups. So, what is spurious wakeups? As mentioned, it is the thread waking up without a notification ... but interestingly, it is *not* common. In most cases, it is merely that way because the native threading system can't make the guarantee. In other words, spurious wakeups should be rare, if they ever happen at all.
So, if spurious wakeups shouldn't really be happening, what is this exactly? The reason is due to hitting a conflict (which is due to implementation detail). Unfortunately, the thread object is already in use as a notification object. The core java library uses the thread object to wake up threads doing a join(). When any thread completes, as part of the clean up process, a notifyAll() is done to wake up the threads waiting to join().
So, when the thread completed, a notification is sent, and your waiting thread also woke up. Arguably, this is just like a spurious wakeup, in that it is waking up unexpectedly, but it is not really the same "spurious wakeup" that the JLS is referring to.