Using wait() and notify()

Let's say you have two threads and they need to talk to each other. For example, let's say Thread A is waiting on Thread B to send a message:

// Thread A public void waitForMessage() {
 while (hasMessage == false) {
 Thread.sleep(100);
 }
}
// Thread B public void setMessage(String message) {
 ...
 hasMessage = true;
}


Although this works, it's a clunky solution. Thread A has to constantly check whether Thread B has sent the message every 100 milliseconds, or 10 times a second. Thread A could oversleep and be late in getting the message. Also, what would happen if several threads were waiting for a message? Wouldn't it be nice if Thread A could just stay idle and be notified when Thread B sends the message? Lucky for us, the wait() and notify() methods provide this capability. The wait() method is used in synchronized blocks of code. When the wait() method executes, the lock is released and the thread waits to be notified. The notify() method is also used in a synchronized block of code. The notify() method notifies one thread waiting on the same lock. If several threads are waiting on the lock, one of them is notified randomly. Here's the updated message code:

// Thread A public synchronized void waitForMessage() {
 try {
 wait();
 }
 catch (InterruptedException ex) { }
}
// Thread B public synchronized void setMessage(String message) {
 ...
 notify();
}


After Thread B calls notify() and leaves its synchronized method (releasing the lock on this), Thread A reacquires the lock and finishes its synchronized block of code. In this case, it just returns. You can also choose to wait for a maximum amount of time. The wait() method can take a maximum amount of time to wait as a parameter:

wait(100);


If the thread is never notified, this is equivalent to putting the thread to sleep for the specified amount of time. Unfortunately, there's no way to tell whether the wait() method returned because of a timeout or because the thread was notified. A second notify method, notifyAll(), notifies all threads waiting on the lock, instead of just one. The wait(), notify(), and notifyAll() methods are methods of the Object class, so any Java object has these methods—just like any Java object can be used as a lock.

Screenshot


   
Comments