Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

notifyAll() instead of notify()  RSS feed

 
merlin bar
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi folks,
Just wondering, from what I've read, there's no harm in replacing all calls to notify() in a program to notifyAll().
It seems that it might wake up threads that may not need waking, but they should be coded well enough to know to go back to sleep.
This approach would make things faster/easier to code I feel.
Regards,
merlin_bar
What d'ye think?
 
Leandro Oliveira
Ranch Hand
Posts: 298
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yes!!! the difference is that notify() chooses one of the waiting threads, and notifyAll() awakens all the waiting threads!!!
 
merlin bar
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks,
also, I meant to say that a well programmed thread will know when to wait() if it has been notified unnecessarily (not sleep() as I said).
Regards,
merlin_bar
 
Leandro Oliveira
Ranch Hand
Posts: 298
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When to wait is a really important point, most of the times, if u have an object and many threads willing for this object's lock, if you use notifyAll() it's often used something like this:
while(!ok){
this.wait();
}
but if you use notify() the following will work:
if(!ok) wait();
notice also that the first case, with while, will work also!!! A good context to use this is in a producer/consumer relationship!!!
the static method sleep of Thread class is not useful, in this case, because the current thread that owns the lock, won't release this lock!!
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It depends. IF the threads are waiting on a shared resource, notifyAll is wasteful, but not very dangerous. If the threads are waiting for some other reason, then waking all threads may lead to bad behavior.
 
Joe Cheng
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
>> It depends. IF the threads are waiting on a shared resource, notifyAll is wasteful, but not very dangerous. If the threads are waiting for some other reason, then waking all threads may lead to bad behavior. <<
I generally lean towards using notifyAll() even in shared resource situations, in case a badly behaving thread is nudged by notify() but itself fails to call notify() (maybe an exception is thrown for some other reason, or the condition it's waiting for hasn't become true and it goes back to waiting).
Anyway, the Doug Lea book goes into some depth about notify() vs. notifyAll() I believe (maybe not though, it's been a while).
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
With all due respect, I don't think a blanket recommendation in favour of notifyAll() is a good idea. The notify() method has its place, as has notifyAll().
  • You use notify() if all waiting threads are interchangeable (this includes the special case of only ever having one waiting thread), and if every single of these threads is able to do whatever it is that needs doing. A good example of this would be a job queue that uses a thread pool to execute jobs; every time a new job is enqueued, you only ever need to wake up one waiting thread which can then run the job and go back to sleep.
  • You use notifyAll() in all other cases. For example, if the job queue from the previous example has a limited size, and job-posting threads wait() on the same monitor lock as the worker threads do, you can no longer use notify() because the threads are no longer interchangeable. You wouldn't know whether you'd be waking up a job-posting thread or a worker thread.
  • Be very, very wary though of using anything other than a while() loop for the wait condition!
    leandro oliveira writes:
    When to wait is a really important point, most of the times, if u have an object and many threads willing for this object's lock, if you use notifyAll() it's often used something like this:
    while(!ok){
    this.wait();
    }
    but if you use notify() the following will work:
    if(!ok) wait();
    Although this looks very plausible, it is actually not true. Even if you use notify(), you will often have to use a while loop rather than a simple "if" for the wait condition.
    The reason, as so often with concurrent programming, is an insidious potential race condition.
    Take the job queue example again that I wrote about above. Assume the dequeuer core is a little bit of code that saysThis looks as if it will work, but it won't. Consider the following scenario.
  • A job gets posted. Posting thread calls notify(), and one of the waiting threads is removed from the wait set and re-enabled for scheduling.
  • Context switch. A worker Thread that has just finished executing its job enters dequeueJob(). It finds a job in the job queue, dequeues and runs it.
  • Context switch. The notified thread starts to execute, calls jobs.removeFirst(), and a NoSuchElementException gets thrown. Congratulations, you now probably have one fewer thread in your thread pool
  • You can use an if statement for your wait condition only if you are really, really sure that the wait condition will be fulfilled when the thread is woken up. This will generally only be the case if there is only ever one single thread. In all other cases, because a good analysis is actually very hard to do, I have no qualms at all in making a blanket recommendation for using a while() loop.
    - Peter
    [ February 24, 2003: Message edited by: Peter den Haan ]
     
    Jim Yingst
    Wanderer
    Sheriff
    Posts: 18671
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I agree with Peter, with the following addendum (which is not too different from what Joe Cheng seems to have been saying):
    With all due respect, I don't think a blanket recommendation in favour of notifyAll() is a good idea
    I'd say that for people who still (after reading the other advice here) aren't really sure yet which is more appropriate for their situation, because they're still learning how wait/notify works or because their code has gotten too complex to tell what's going on, notifyAll() is the safer one to go with. You may get code that runs a little slower than it might, but you're less likely to get code that simply stops because just one of your threads failed to call notify() again when it's done. That said, if you are in this situation it really behooves you to either (a) learn threads better ASAP, or (b) refactor your code so you can better understand how it works. And if one of your threads fails to call notify() when it should, it would probably also fail to call notifyAll(), and you need to fix that. It's just that the chance of it being a problem decreases (but does not vanish) if you use notifyAll().
    Threads are extremely useful, but debugging them can be a royal pain in the butt. So extra effort to understand them and keep them manageable is well worth your time.
    [ February 24, 2003: Message edited by: Jim Yingst ]
     
    Joe Cheng
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ah, now I've got the Lea book firmly in hand... here's what he has to say about it (p. 191):
    [Talking about a bounded counter, where threads wait for the count to be greater than MIN or less than MAX]
    ...It would not suffice here to use notify, which wakes up only one thread (if one exists). The JVM might pick a thread waiting for a condition that does not hold without picking the possibly many that could continue.
    <snip>
    However, in some other classes, you can reduce the context-switch overhead associated with notifications by using a single notify rather than notifyAll. Single notifications can be used to improve performance when you are sure that at most one thread needs to be woken. This applies when:
  • All possible waiting threads are necessarily waiting for conditions relying on the same notifications, usually the exact same condition.
  • Each notification intrinsically enables at most a single thread to continue. Thus it would be useless to wake up others.
  • You can accomodate uncertainties surrounding the possibility that an interrupt and a notify may occur at about the same time. In this case, the one thread that was notified is about to terminate. You might want another thread to receive notification instead, but this is not automatically arranged. (The issue does not arise with notifyAll since all threads are woken.)


  • <snip>
    In open, extensible designs, the conditions under which notify apply are rather special and fragile. The use of notify, and optimizations of guarded constructions more generally, are common sources of error. As a general design tactic, it is a better idea to isolate uses of notify to concurrency control utility classes that can be heavily optimized and carefully reviewed and tested.

    I'll stop there, since I'm probably pushing the boundaries of fair-use copyright laws...
     
    Max Habibi
    town drunk
    ( and author)
    Sheriff
    Posts: 4118
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This is consistant with my own understanding, and the advice offered by Allen Holub, the other part of the holy trinity of Threading.
    All best,
    M, author
    The Sun Certified Java Developer Exam with J2SE 1.4
     
    merlin bar
    Ranch Hand
    Posts: 54
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Right,
    there's a lot to chew on here so I can't really comment yet, but thanks for all the input so far. I'll be back
     
    Jim Yingst
    Wanderer
    Sheriff
    Posts: 18671
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Allen Holub, the other part of the holy trinity of Threading.
    By which you mean Allen Holub, Doug Lea, and ??? There are a number of people who know their stuff here; I'm not sure who else is regarded as pre-eminent.
     
    Dan Bizman
    Ranch Hand
    Posts: 387
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I would add one other thing:
    Because Java cannot guarantee that all threads of the same priority are in fact given equal time, nor that they'll be notified in any particular order, if you've saved reference to some threads and you want to make sure they're all given a chance, you must use notify. If you use notifyAll, then it is possible that one thread will never wake up in time to grab the resource you are offering. If instead, you find that actual thread that is "next in line" and notify only that thread, you'll know you are notifying them in order. (Did that make sense?)
     
    merlin bar
    Ranch Hand
    Posts: 54
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Yes, that does make sense. I'm getting the concepts of the different queues associatied with a resource. I'm reading an article on advanced threads, which explains the details / technicalities. Together with the replies to this post, it's invaluable!!
    [ February 27, 2003: Message edited by: merlin bar ]
     
    Jim Yingst
    Wanderer
    Sheriff
    Posts: 18671
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    (Did that make sense?)
    Not to me, unfortunately.
    If instead, you find that actual thread that is "next in line" and notify only that thread, you'll know you are notifying them in order.
    But how do you choose which thread you're notifying? if a monitor has more than one thread wait()ing on it, then when you call notify() one of those threads will be selected at random and notified - other threads will be ignored. If you want to guarantee that a specific thread is notified, you can only do that by making sure no other threads are waiting for that monitor. This is the basis of the Tom Cargill's Specific Notification Pattern which is also discussed by Peter Hagger.
     
    Max Habibi
    town drunk
    ( and author)
    Sheriff
    Posts: 4118
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Jim Yingst:
    Allen Holub, the other part of the holy trinity of Threading.
    By which you mean Allen Holub, Doug Lea, and ??? There are a number of people who know their stuff here; I'm not sure who else is regarded as pre-eminent.

    I mean Scott Oaks, which means that I should include Henry Wong. Still, Scott's the one I was thinging of.
    M, author
    The Sun Certified Java Developer Exam with J2SE 1.4
     
    Mr. C Lamont Gilbert
    Ranch Hand
    Posts: 1170
    Eclipse IDE Hibernate Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Jim Yingst:
    I agree with Peter, with the following addendum (which is not too different from what Joe Cheng seems to have been saying):
    With all due respect, I don't think a blanket recommendation in favour of notifyAll() is a good idea
    I'd say that for people who still (after reading the other advice here) aren't really sure yet which is more appropriate for their situation, because they're still learning how wait/notify works or because their code has gotten too complex to tell what's going on, notifyAll() is the safer one to go with...

    Jim, this is what we call "riding the fence."
    Is their ever a reason to teach bad behavior? Especially when a programmer is learning. notify() and notifyAll() are 2 different methods which are _never_ interchangeable. They will always cause different behavior in a program because they do different things.
    I would suggest that even those learning should use the appropriate method from the very start.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!