Difference between notify and notifyAll
NotifyAll wakes up all the threads that are waiting on the specified object lock. Please note that it might be necessary to use notifyAll instead of notify in cases when a specific or a specific subset out of a set of threads need to be notified. For instance: in a producer – consumer scenario, the producer should use notifyAll to wake up all the consumers out of which only one would be able to utilize the product that the producer has available. The producer might have 2 quantities of products available for consumption and there might be consumers that require more than 2 and so just using notify might wake up those and there would be no progress.
Also note that notify will not relenquish the lock like wait does. Notify will only relenquish the lock once the synchronized section is exited. The thread invoking notify might continue to run although the thread that is waiting has been notified and is now in a RUNNABLE state ready to acquire the lock.
Note that the round-robin scheduling might appear to be fair but it is not in the following case (in case of a single CPU machine):
- Intermediate results from a calculation are not required – all that is required are the final results. For instance, if there are 5 threads started to do a calculation that provides a result in 5 seconds, then no matter what kind of time slicing is done, the average time for producing the final result is equal to or more than the average time in a non-timesliced version.
On the other hand, if intermediate results are required then the round-robin (timesliced) scheduling is the fairest. It the timeslice is 1 second, then the average time for each thread to produce an answer would be (1+2+3+4+5)/5 = 3 seconds. On the other hand, for a non-timesliced version, the average would be (1+6+11+16+21)/5 = 11 seconds.
For a multiple CPU machine, it gets complicated.
If intermediate results are not required (on a 4 CPU machine), we have:
- Average for a non-timesliced version = (5+5+5+5+10)/5 = 6 secs.
- Average for a timesliced version = (5+5+5+7+8)/5 = 6 secs (for a timeslice of 2 secs)
If intermediate results are required:
- Average for a non-timesliced version would be (1+1+1+1+6)/5 = 2 secs
- Average for a timesliced version would be (1+1+1+1+2)/5 = 1.2 secs (for a timeslice of 1 sec)
Note that for intermediate results, the timesliced version of scheduling is the most fairest.