system, the consumer would waste many CPU cycles while it waited for the producer to
produce. Once the producer was finished, it would start polling, wasting more CPU cycles
waiting for the consumer to finish, and so on. Clearly, this situation is undesirable.
To avoid polling, Java includes an elegant interprocess communication mechanism via
the wait( ), notify( ), and notifyAll( ) methods. These methods are implemented as final
methods in Object, so all classes have them. All three methods can be called only from
within a synchronized context. Although conceptually advanced from a computer science
perspective, the rules for using these methods are actually quite simple:
· wait( ) tells the calling thread to give up the monitor and go to sleep until some
other thread enters the same monitor and calls notify( ).
· notify( ) wakes up a thread that called wait( ) on the same object.
· notifyAll( ) wakes up all the threads that called wait( ) on the same object. One of
the threads will be granted access.
These methods are declared within Object, as shown here:
final void wait( ) throws InterruptedException
final void notify( )
final void notifyAll( )
Additional forms of wait( ) exist that allow you to specify a period of time to wait.
Before working through an example that illustrates interthread communication, an
important point needs to be made. Although wait( ) normally waits until notify( ) or
notifyAll( ) is called, there is a possibility that in very rare cases the waiting thread could be
awakened due to a spurious wakeup. In this case, a waiting thread resumes without notify( )
or notifyAll( ) having been called. (In essence, the thread resumes for no apparent reason.)
Because of this remote possibility, Sun recommends that calls to wait( ) should take place
within a loop that checks the condition on which the thread is waiting. The following
example shows this technique.
Let's now work through an example that uses wait( ) and notify( ). To begin, consider
the following sample program that incorrectly implements a simple form of the producer/
consumer problem. It consists of four classes: Q, the queue that you're trying to synchronize;
Producer, the threaded object that is producing queue entries; Consumer, the threaded
object that is consuming queue entries; and PC, the tiny class that creates the single Q,
Producer, and Consumer.
// An incorrect implementation of a producer and consumer.
class Q {
int n;
synchronized int get() {
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n) {
this.n = n;
System.out.println("Put: " + n);
}
}
Search WWH :
Custom Search
Previous Page
Java SE 6 Topic Index
Next Page
Java SE 6 Bookmarks
Home