Java Reference
In-Depth Information
Caution
Although Figure 4-4 shows the threads being notified in the same order they called
wait
,this
should never be relied on. The order in which threads are notified, and the order in which they regain owner-
ship of the lock on the common object, is entirely at the discretion of the JVM's thread scheduler.
■
In general, you would use
notify
only when you are certain that the thread that will be
notified will be able to use the notification. If you have multiple threads that you are certain
will be able to use the notification but you want only one of them to transition to the runnable
state, then you should use
notify
. However, in this case you must ensure that the remaining
threads do not stay in limbo—some thread will have to notify them at an appropriate time
that they can continue processing. This is complex and requires detailed analysis in order to
get it right. If you have multiple threads waiting on one event but they have different condi-
tions to meet, you are better off calling
notifyAll
so that all the threads will recheck their
condition. As an example, consider the following code snippets:
Producer Thread:
synchronized (lock) {
value = Math.random();
lock.notifyAll();
}
Consumer Thread 1:
synchronized (lock) {
while (value < 0.5) {
lock.wait();
}
}
Consumer Thread 2:
synchronized (lock) {
while (value >= 0.5) {
lock.wait();
}
}
This code shows one example where calling
notifyAll
is preferable to calling
notify
. By
calling
notifyAll
after setting
value
, the producer can be sure that both consumers will check
the current contents of the
value
variable, and one of them will be able to continue process-
ing. If
notify
had been used instead of
notifyAll
, it is possible that after setting
value
, the
wrong thread may have been notified, and upon finding that the
value
variable did not con-
tain the desired number, would have gone back to the
Thread.State.WAITING
state, meaning
that neither consumer thread would be working!