aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes notify() vs notifyAll() Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "notify() vs notifyAll()" Watch "notify() vs notifyAll()" New topic
Author

notify() vs notifyAll()

David A. Scott
Ranch Hand

Joined: Apr 13, 2006
Posts: 55
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
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42276
    
  64
This thread -coincidentally named exactly the same as this one- gives a good overview of the issues involved.


Ping & DNS - my free Android networking tools app
David A. Scott
Ranch Hand

Joined: Apr 13, 2006
Posts: 55
heh - thanks.

I thought I'd done a reasonable search.
David A. Scott
Ranch Hand

Joined: Apr 13, 2006
Posts: 55
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.
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
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

Joined: Apr 13, 2006
Posts: 55
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 ]
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

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


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Petr Hejl
Ranch Hand

Joined: Feb 26, 2006
Posts: 68
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

Joined: Apr 13, 2006
Posts: 55

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
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

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

Joined: Apr 13, 2006
Posts: 55
Thanks.

I will look further into ReentrantLock.

David
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: notify() vs notifyAll()