Java Reference
In-Depth Information
The Producer thread remains in the waiting state until another thread notifies the
Producer that it may proceed—at which point the Producer returns to the runnable state
and attempts to implicitly reacquire the lock on the SynchronizedBuffer object. If the
lock is available, the Producer thread reacquires it, and method blockingPut continues
executing with the next statement after the wait call. Because wait is called in a loop, the
loop-continuation condition is tested again to determine whether the thread can proceed.
If not, then wait is invoked again—otherwise, method blockingPut continues with the
next statement after the loop.
Line 22 in method blockingPut assigns the value to the buffer . Line 26 sets occu-
pied to true to indicate that the buffer now contains a value (i.e., a consumer can read
the value, but a Producer cannot yet put another value there). Line 28 invokes method
displayState to output a message indicating that the Producer is writing a new value into
the buffer . Line 30 invokes method notifyAll (inherited from Object ). If any threads
are waiting on the SynchronizedBuffer object's monitor lock, those threads enter the
runnable state and can now attempt to reacquire the lock . Method notifyAll returns
immediately, and method blockingPut then returns to the caller (i.e., the Producer 's run
method). When method blockingPut returns, it implicitly releases the monitor lock on the
SynchronizedBuffer object.
Method blockingGet and the Consumer Thread
Methods blockingGet and blockingPut are implemented similarly. When the Consumer
thread's run method invokes synchronized method blockingGet , the thread attempts to
acquire the monitor lock on the SynchronizedBuffer object. If the lock is available, the
Consumer thread acquires it. Then the while loop at lines 37-43 determines whether oc-
cupied is false . If so, the buffer is empty, so line 40 outputs a message indicating that the
Consumer thread is trying to read a value, and line 41 invokes method displayState to
output a message indicating that the buffer is empty and that the Consumer thread is wait-
ing . Line 42 invokes method wait to place the thread that called method blockingGet
(i.e., the Consumer ) in the waiting state for the SynchronizedBuffer object. Again, the call
to wait causes the calling thread to implicitly release the lock on the SynchronizedBuffer
object, so another thread can attempt to acquire the SynchronizedBuffer object's lock
and invoke the object's blockingPut or blockingGet method. If the lock on the Synchro-
nizedBuffer is not available (e.g., if the Producer has not yet returned from method
blockingPut ), the Consumer is blocked until the lock becomes available.
The Consumer thread remains in the waiting state until it's notified by another thread
that it may proceed—at which point the Consumer thread returns to the runnable state and
attempts to implicitly reacquire the lock on the SynchronizedBuffer object. If the lock is
available, the Consumer reacquires it, and method blockingGet continues executing with
the next statement after wait . Because wait is called in a loop, the loop-continuation con-
dition is tested again to determine whether the thread can proceed with its execution. If
not, wait is invoked again—otherwise, method blockingGet continues with the next
statement after the loop. Line 47 sets occupied to false to indicate that buffer is now
empty (i.e., a Consumer cannot read the value, but a Producer can place another value in
buffer ), line 49 calls method displayState to indicate that the consumer is reading and
line 51 invokes method notifyAll . If any threads are in the waiting state for the lock on
this SynchronizedBuffer object, they enter the runnable state and can now attempt to
 
Search WWH ::




Custom Search