Java Reference
In-Depth Information
The threads in the entry set are blocked and they are ready to grab access to the monitor as soon as possible.
The threads in the wait set are waiting for some condition to occur. A thread that has ownership of the monitor must
notify the threads waiting in the wait set about the fulfillment of the conditions on which they are waiting. In Java, the
notification is made by calling the
notify()
and
notifyAll()
methods of the
java.lang.Object
class. Like the
wait()
method, the
notify()
and
notifyAll()
methods are also declared
final
. Like the
wait()
method, these two methods
must be called by a thread using an object whose monitor has already been acquired by the thread. If a thread calls
these methods on an object before acquiring the object's monitor, a
java.lang.IllegalMonitorStateException
is
thrown. The call to the
notify()
method wakes up one thread from the wait set, whereas the call to the
notifyAll()
method wakes up all threads in the wait set. In case of the
notify()
method call, the thread that is woken up is chosen
arbitrarily. Note that when a thread calls the
notify()
or
notifyAll()
method, it still holds the lock on the object's
monitor. Threads in the wait set are only woken up by the
notify()
or
notifyAll()
call. They do not acquire the
object's monitor lock immediately. When the thread that called the
notify()
or
notifyAll()
method releases the
object's monitor lock by “Release and exit” or “Release and wait,” the woken up threads in the wait set competes with
the threads in the entry set to acquire the object's monitor again. Therefore, a call to the
notify()
and
notifyAll()
serves only as a wake-up call for threads in the wait set and it does not guarantee access to the object's monitor.
■
there is no way to wake up a specific thread in the wait set. the call to
notify()
chooses a thread
arbitrarily, whereas the call to
notifyAll()
wakes up all threads. Use
notifyAll()
when you are in doubt about
which method to use.
Tip
The following snippet of code shows a pseudo code for using the
notifyAll()
method along with the
wait()
method. You may observe that the call to the
wait()
and
notify()
methods are made on the same object,
because if
objectRef.wait()
puts a thread in the wait set of the
objectRef
object, the
objectRef.notify()
or
objectRef.notifyAll()
method will wake that thread from the wait set of the
objectRef
object.
public class WaitAndNotifyMethodCall {
private Object objectRef = new Object();
public synchronized void someMethod_1() {
while (some condition is true) {
this.wait();
}
if (some other condition is true) {
// Notify all waiting threads
this.notifyAll();
}
}
public static synchronized void someMethod_2() {
while (some condition is true) {
WaitAndNotifyMethodCall.class.wait();
}
if (some other condition is true) {
// Notify all waiting threads
WaitAndNotifyMethodCall.class.notifyAll();
}
}