• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

notify() vs notifyAll()

 
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Obviously since I'm here I have my SCJP cert so I know what the difference between the two is BUT I'm still not quite clear on when it is appropriate to use which.

My unlocking method for the B&S assignment looks something like the following. (approximately as I don't actually have the source to hand!)



As there may be many threads waiting for the locked object, would it be appropriate to use notifyAll() here? Or can I rely on each thread getting the lock eventually and releasing it when it is done?

I have tested the lock/unlock methods using 1000 threads and only 4 available record numbers and it worked ok (took a long time to finish!) but I'm not sure if I'm missing something?

This may be obvious to you but my Java concurrency experience begins and ends with what was required for the programmer exam.

Cheers

David
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This thread -coincidentally named exactly the same as this one- gives a good overview of the issues involved.
 
David A. Scott
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
heh - thanks.

I thought I'd done a reasonable search.
 
David A. Scott
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So I think this comment from Henry Wong seems to cover what I'm talking about. Releasing the lock in my case can only possibly satisfy the needs of a single thread (at a time) so I am right to stick with notify().

Anyone have any further comments?


IMHO, whether you call notify() or notifyAll() is dependant on the state that you just changed. If you changed the state, in a manner that can satisfy one waiting thread, then you call notify. If you change the state that can satisfy multiple waiting threads -- like releasing a group of semaphores, or shutting down the system (special case) -- then you call notifyAll().

I don't think it matters if you have one waiting thread, many waiting threads, or even zero waiting threads. You should design your application in a fashion where you actually don't care how many threads are waiting, if there are even any. This is why you should also (1) check the state prior to waiting, and (2) check again after waiting.

 
Ranch Hand
Posts: 68
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It depends on behaviour of your lock method. What happens if you unlock record 1 and the thread that jvm will choose for wake up (through notify) will be waiting for record 2? It could cause a deadlock...
 
David A. Scott
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Petr Hejl:
It depends on behaviour of your lock method. What happens if you unlock record 1 and the thread that jvm will choose for wake up (through notify) will be waiting for record 2? It could cause a deadlock...



My lock/unlock method is synchronized on a HashMap which acts as a lookup of locked records (and their associated cookies).

The way I see it working :-

Thread 1 Successfully Locks record 10
Thread 2 Attempts to Lock record 10 but can't so it wait()'s
Thread 3 Attempts to Lock record 20 but can't so it wait()'s
Thread 1 Unlocks record 10 and issues a notify()

At this point EITHER - Thread 2 gets the lock on record 10 OR Thread 3 gets the lock on record 20.

If it is the latter I am presuming that the notify() Thread 3 issues will release the wait() on thread 2? Am I being naive?
[ February 28, 2007: Message edited by: David A. Scott ]
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Petr Hejl:
It depends on behaviour of your lock method. What happens if you unlock record 1 and the thread that jvm will choose for wake up (through notify) will be waiting for record 2? It could cause a deadlock...



Agreed. For notify() to work properly, the threads that are waiting should be waiting for the same resource / event -- as it is not possible to choose which thread to wake up.

Henry
 
Petr Hejl
Ranch Hand
Posts: 68
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
David,
it is all written in javadoc.

1. Thread 1 locks record 10
2. Thread 2 locks record 20
3. Thread 3 wants to lock record 10 => wait
4. Thread 4 wants to lock record 20 => wait
5. Thread 2 unlocks record 20 and call notify()
6. Thread 3 wokes up, but it still can't acquire lock on 10 => wait
7. Deadlock - no notify will ever occur
 
David A. Scott
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


1. Thread 1 locks record 10
2. Thread 2 locks record 20
3. Thread 3 wants to lock record 10 => wait
4. Thread 4 wants to lock record 20 => wait
5. Thread 2 unlocks record 20 and call notify()
6. Thread 3 wokes up, but it still can't acquire lock on 10 => wait
7. Deadlock - no notify will ever occur



So the problem is that if a notify() occurs and there is nothing able to act on it then we effectively have wasted a notify(). And then there are too few notify()'s to serve all the wait()'s.

So a straight swith from notify() to notifyAll() would remedy this because each waiting thread would be notfied?
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

So a straight swith from notify() to notifyAll() would remedy this because each waiting thread would be notfied?



If you have threads waiting on the same object for different conditions, changing notify() to notifyAll(), is probably the easiest and quickest remedy to implement -- although probably not the best.

Another option is to look at the ReentrantLock class (assuming that you have Java 5). It implements a basic mutex, which is similar to Java synchronization mechanism. It also has a method that returns a Condition variable which is similar to Java wait and notify mechanism.

The interesting part of this class, is that you can call the method to get as many condition variables as you want. Basically, you can get a bunch of different objects to use to wait on conditions (AKA condition variables) -- condition variables that share the same mutex.

Henry
 
David A. Scott
Ranch Hand
Posts: 55
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks.

I will look further into ReentrantLock.

David
 
Do not set lab on fire. Or this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic