Simply put, it depends on why your threads are waiting to be notified. Do you want to tell one of the waiting threads that something happened, or do you want to tell all of them at the same time?
In some cases, all waiting threads can take useful action once the wait finishes. An example would be a set of threads waiting for a certain task to finish; once the task has finished, all waiting threads can continue with their
business. In such a case you would use notifyAll() to wake up all waiting threads at the same time.
Another case, for example mutually exclusive locking, only one of the waiting threads can do something useful after being notified (in this case acquire the lock). In such a case, you would rather use
notify(). Properly implemented, you could use notifyAll() in this situation as well, but you would unnecessarily wake threads that can't do anything anyway.
notify vs notifyAll in Java
tricky Java question, which iseasy to answer but once Interviewer ask followup questions, you either gotconfused or not able to provide clear cut and to the point
answers. Maindifference between notify and notifyAll is that notify methodwill only notify one
Thread and notifyAll methodwill notify all Threads which arewaiting on that monitor or lock. By the way this is something you have beenreading in all over places and to be frank, this
statement despite being correct is not complete and its verydifficult to understand
differencebetween notify vs notifyAll by just reading this statement. Lot of questionscomes in mind like
Java and I had touched based onthis on my earlier article
why wait and notify must be called fromsynchronized context. In order to get answer of those questions andunderstand difference between notify and notifyAll we will use a simple JavaThread example using wait and notify code :
popular multi-threading interviewquestion in Java. When you call notify only oneof waiting thread will be woken and its not guaranteed which thread will bewoken, it depends upon Thread scheduler. While if you call notifyAll method, allthreads waiting on
that lock will be woken up, but again all woken thread willfight for lock before executing remaining code and that's why wait is called onloop because if multiple threads are woken up, the thread which will get lockwill first execute and it may reset waiting
condition, which will forcesubsequent threads to
wait. So key differencebetween notify and notifyAll is that notify() will causeonly one thread to wake up while notifyAll method willmake all thread to wake up.
applying little common sense. You can use notify over notifyAll if allthread are waiting for same condition and only one Thread at a time can benefitfrom condition becoming true. In this case notify isoptimized call over notifyAll
because waking up all of thembecause we know that only one thread will benefit and all other will wait again,so calling notifyAll method is just waste of cpu
cycles. Though this looksquite reasonable there is still a caveat that unintended recipient swallowingcritical
notification. by using notifyAll we ensurethat all recipient will get notify. Josh bloach has explained this in gooddetail in his book
Effective Java , I highly recommend this book if you haven'tread them already. Another one you can try is Concurrency Practice in Java andJava Thread, which discusses
wait and notify methods ingood details.
Example of notify and notifyAll method inJava
go is false, remember boolean go isa
volatile variable, so that allthreads will see its updated value. Initially three threads WT1, WT2,WT3 will wait because variable go is false than onethread NT1 will make go true and notifyall threads by calling notifyAll method or notify just one threadby
calling notify() method. In case of notify() call thereis no guarantee which thread will woke up and you can see it by running this Javaprogram multiple times. In case of notifyAll all threadwill woke up but they will compete for monitor or lock and the Thread
whichwill get the lock first will finish its execution and resetting go to false which willforce other two threads still waiting. At the end of this program you will havetwo threads waiting and two threads including notification thread finished.Program will
not terminate because other two threads are still waiting and theyare not
daemon threads. Purpose ofthis notify and notifyAll example is to show you How to usethem and How notify and notifyAll method works in Java.
java.util.logging.Level;
import
java.util.logging.Logger;
/**
* Java program to demonstrate How to use notify and notifyAll methodin Java and
*/
public classNotificationTest
{
private volatile
booleango = false;
public static
voidmain(String args[])
throwsInterruptedException
{
finalNotificationTest test =
newNotificationTest();
Runnable waitTask = new Runnable(){
@Override
publicvoid run(){
try
{
test.shouldGo();
} catch
(InterruptedException ex)
{
Logger.getLogger(NotificationTest.class.getName()).
log(Level.SEVERE,
null,ex);
}
System.out.println(Thread.currentThread()
+ " finishedExecution");
}
};
Runnable notifyTask = new Runnable(){
@Override
publicvoid run(){
test.go();
System.out.println(Thread.currentThread()
+ " finishedExecution");
}
};
Thread t1 = newThread(waitTask,
"WT1");
//will wait
Thread t2 = newThread(waitTask,
"WT2");
//will wait
Thread t3 = newThread(waitTask,
"WT3");
//will wait
Thread t4 = newThread(notifyTask,"NT1");
//will notify
//starting allwaiting thread
t1.start();
t2.start();
t3.start();
//pause to ensureall waiting thread started successfully
Thread.sleep(200);
//starting notifyingthread
t4.start();
}
/*
* wait and notify can only be called from synchronizedmethod or bock
*/
private synchronized
voidshouldGo()
throwsInterruptedException
{
while(go
!= true){
System.out.println(Thread.currentThread()
" is going to wait on this object");
wait();
//release lockand reacquires on wakeup
System.out.println(Thread.currentThread()
+ " is wokenup");
}
go = false;
//resettingcondition
}
/*
* both shouldGo() and go() are locked on current objectreferenced by "this" keyword
*/
private synchronized
voidgo()
{
while (go ==
false){
System.out.println(Thread.currentThread()
go = true;
//makingcondition true for waiting thread
//notify();// only one out of three waiting thread WT1, WT2,WT3 will woke up
notifyAll();
// all waitingthread WT1, WT2,WT3 will woke up
}
}
}
Output in caseof using notify
Thread[WT1,5,main] is going to wait on
thisobject
Thread[WT3,5,main] is going to wait on
thisobject
Thread[WT2,5,main] is going to wait on
thisobject
Thread[NT1,5,main] is going to notify all or one thread waiting on
this object
Thread[WT1,5,main] is woken up
Thread[NT1,5,main] finished Execution
Thread[WT1,5,main] finished Execution
Output in caseof calling notifyAll
Thread[WT1,5,main] is going to wait on
thisobject
Thread[WT3,5,main] is going to wait on
thisobject
Thread[WT2,5,main] is going to wait on
thisobject
Thread[NT1,5,main] is going to notify all or one thread waiting on
this object
Thread[WT2,5,main] is woken up
Thread[NT1,5,main] finished Execution
Thread[WT3,5,main] is woken up
Thread[WT3,5,main] is going to wait on
thisobject
Thread[WT2,5,main] finished Execution
Thread[WT1,5,main] is woken up
Thread[WT1,5,main] is going to wait on
thisobject
deadlock,
race condition and
thread-safety, inter thread communication is one of thefundamental of concurrent
programming in Java.
tutorial:
producer consumer pattern in Java.
synchronized method or block,you need to call notify method on object on which other threads are waiting.
wait and notify method.