Java Reference
In-Depth Information
In the case of fetching an item from the buffer, the condition that allows the operation to
proceed is that the buffer is not empty . If the condition in question is true, the operation
may proceed; if it's false, the thread must wait until it becomes true. When a thread is
waiting on a condition, it's removed from contention for the processor and placed into the
waiting state and the lock it holds is released.
Methods wait , notify and notifyAll
Object methods wait , notify and notifyAll can be used with conditions to make threads
wait when they cannot perform their tasks. If a thread obtains the monitor lock on an object,
then determines that it cannot continue with its task on that object until some condition is
satisfied, the thread can call Object method wait on the synchronized object; this releases
the monitor lock on the object, and the thread waits in the waiting state while the other
threads try to enter the object's synchronized statement(s) or method(s). When a thread
executing a synchronized statement (or method) completes or satisfies the condition on
which another thread may be waiting, it can call Object method notify on the synchro-
nized object to allow a waiting thread to transition to the runnable state again. At this
point, the thread that was transitioned from the waiting state to the runnable state can at-
tempt to reacquire the monitor lock on the object. Even if the thread is able to reacquire the
monitor lock, it still might not be able to perform its task at this time—in which case the
thread will reenter the waiting state and implicitly release the monitor lock . If a thread calls
notifyAll on the synchronized object, then all the threads waiting for the monitor lock
become eligible to reacquire the lock (that is, they all transition to the runnable state).
Remember that only one thread at a time can obtain the monitor lock on the object—
other threads that attempt to acquire the same monitor lock will be blocked until the mon-
itor lock becomes available again (i.e., until no other thread is executing in a synchronized
statement on that object).
Common Programming Error 23.1
It's an error if a thread issues a wait , a notify or a notifyAll on an object without hav-
ing acquired a lock for it. This causes an IllegalMonitorStateException .
Error-Prevention Tip 23.2
It's a good practice to use notifyAll to notify waiting threads to become runnable . Doing
so avoids the possibility that your program would forget about waiting threads, which
would otherwise starve.
Figures 23.16 and 23.17 demonstrate a Producer and a Consumer accessing a shared
buffer with synchronization. In this case, the Producer always produces a value first , the
Consumer correctly consumes only after the Producer produces a value and the Producer
correctly produces the next value only after the Consumer consumes the previous (or first)
value. We reuse interface Buffer and classes Producer and Consumer from the example in
Section 23.5, except that line 28 is removed from class Producer and class Consumer .
Class SynchronizedBuffer
The synchronization is handled in class SynchronizedBuffer 's blockingPut and blocking-
Get methods (Fig. 23.16), which implements interface Buffer (line 4). Thus, the Producer 's
and Consumer 's run methods simply call the shared object's synchronized blockingPut and
 
Search WWH ::




Custom Search