Perhaps I should give more detail on why I ask this.
I have been given a snippet of code.
class FCFSImpl implements CCInterface{
private int current turn = 0;
private int next ticket = 0;
Threads take a ticket and wait until their turn.
synchronized void enter() throws InterruptedException{
int myTicket = nextTicket ++;
while (currentTurn < myTicket)
wait();
}
synchronized void exit(){
current turn ++;
notifyAll();
}
}
and I am asked to change this to us e notify() instead of notifyAll().
Why would I want to? It doesn't yet make sense.
If the woken thread is chosen randomly it would need to check it was the correct one and if not, notify() again for another thread.
I thought perhaps something like this to also allow it to loop round to zero when a finite number is reached ...
synchronized void enter() throws InterruptedException{
if(nextTicket == maxInteger){
nextTicket=0;
}
else{}
int myTicket = nextTicket ++;
while (currentTurn != myTicket){
notify();
try{
wait();
}
catch (InterruptedException e){
}
}
}
synchronized void exit(){
if (currentTurn == maxInteger){
currentTurn=0;
}
else{
currentTurn ++;
}
notify();
}
}
If this is the answer I still am unsure what advantage there would be.
One way to think of the wait/notify protocol is to imagine an item of data such as an integer variable as if it were a field in a database. If you do not have some locking mechanism in the database you stand a chance of corruption to the data.
Thus one user might retrieve the data and perform a calculation and write back the data. If in the meantime someone else has retrieved the data, performed the calculation and written it back, the second users calculations will be lost when the first person writes back to the database. In the way that a database has to handle updates at unpredictable times, so a multi threaded program has to cater for this possibility.
A call to wait from within synchronized code causes the thread to give up its lock and go to sleep. This normally happens to allow another thread to obtain the lock and continue some processing. The wait method is meaningless without the use of notify or notifyAll which allows code that is waiting to be notified that it can wake up and continue executing
As to why notify() might occasionally be preferable to notifyAll(): it's called the thundering herd problem.
Imagine you have a large number of worker threads, and you want to give some work to one of them. If you use notifyAll(), all but one wake up, notice there is nothing to do, and go back to sleep. The thread scheduler ends up eating a lot of CPU unnecessarily. There can also be unwanted cache effects - each worker's local thread state gets brought to memory cache for a brief time, throwing out useful stuff.
But in this case you want to wake up threads in a specific order. That's a bit more work...
sjasja
Thank you for that.
Actually I got to thinking, perhaps because less threads are likely to get notified then there may be less work but your point about the cache being filled unecessarily was something I totally missed.
I assume then that the latter would take longer though.
Cheers :o)
I have just been shown how to do a FIFO with notify()
http://www.awprofessional.com/articles/printerfriendly.asp?p=31539&rl=1
Right at the bottom
3.7.3.2 FIFO semaphores
Probably a bit more than I wanted for this exercise but interesting never the less.
:O)