I� am a bit confused about when notify or notifyAll should be call and am hoping some body might be able to explain a few things for me.
Should notify or notifyAll be called at the end of every synchronized block or will notify be called automatically when the synchronized block is exited?
If a synchronized block is interrupted for some reason eg an Exception is caught should notify or notifyAll all be called?
If a method is synchronized should notify or notifyAll be called before that method is returned?
If no for all of the above when should notify or notifyAll be called?
Thanks in advance for any replys
I was actually confused about this myself, until a fellow rancher showed me the errors of my ways.
When a thread tries to enter a synchronized block, it needs to get the exclusive lock on whatever object is being used for the locking. If another thread has the lock, it goes into a blocked state. Whenever the thread that held the lock exits the synchronized block, it gives up the lock, and a blocked thread will automatically grab it and become active. You don't have to call anything special in the code.
notify and notifyAll are used to wake up waiting threads, or threads that have called the wait() method. When a waiting thread is notified, it tries to grab the exclusive lock, and if it can't, enters the blocked state. Hope that helped!
to avoid digging your own trap I recommend to use notifyAll only, not notify. Besides always call wait inside a loop, e. g.
I recommend Effective Java for best practices in this matter (and many other contexts). Might be good to wait for a 5.0-adjusted edition, though.
Originally posted by Conan Elvitaro:
to avoid digging your own trap I recommend to use notifyAll only, not notify.
Generally, notifyAll() is "preferred" over notify() because either (a) the wrong thread is awoken, or (b) notifications are lost. Neither of these reasons should be considered valid. you should not have threads share locks if they are waiting for different conditions/states. And you should set variables during the synchronization block to prevent notifications from being lost.
IMO, the only reasons for using notify all is when (a) a condition is changed that can satisfy more than one thread or (b) a condition has changed when all threads must respond to. You shouldn't be using notifyAll() just because you can't get notify() to work correctly.
[ March 24, 2005: Message edited by: Henry Wong ]
This is often the case with deleted records, so once again, I would recommend using notifyAll() for this assignment.
(a) a condition is changed that can satisfy more than one thread
Also, in this assignment, many are following the example from Max's book and using a collection such as a HashMap to logically lock records. In this situation, all threads are using the HashMap as the lock object, but waiting on different conditions (whether or not a specific record number exists in the HashMap). Only using notify() in the unlock can potentionally cause deadlock.
You should not have threads share locks if they are waiting for different conditions/states.
Thanks for the replys. Andrew I have updated my profile but not sure if it changes my display name. How do i do that?
I'am still a bit confused about when i should call notify or notifyAll. I understand the difference between them and I know when not to call them. But am still a bit confused about where exactly i should call one of them.
If i have a wait() call inside a synchronized block should I call notifyAll/notify at the end of that synchronized block?
Is this correct use of notifyAll? If it is not, when for the above scenario should notifyAll/notify be called?
Thanks in advance.
I told you already to call wait only inside a loop like that:
The right moment to call notifyAll is when you have a good reason to believe that maybe (or for sure) the condition (a volatile boolean field named "finished" in this case, but it can also be an other condition) has changed.
I actually have wait() inside a while loop but left it out of the snippet i put in my last post. Sorry.
I think I understand now. But just to be sure. If i have the following:
(lockedRecords is a HashMap)
Where ever I make a change to the lockedRecords I should call notify/notiyAll?
the major difference between your case and my case is that in I synchronize and wait on an Integer that only represents one record.
The consequence is that you really HAVE TO use notifyAll whenever you remove anything from lockedRecords. I could as well use notify, I just don't because I follow other rules than Henry does. (He made a good point though, and I will reconsider it for the future.)
So yes, call notifyAll if you want to keep the code you showed us. Unlike me you have to rely on the while (condition) and on the notifyAll to make it work.