Java Reference
In-Depth Information
48
49
displayState( "Consumer reads " + buffer); // for demo only
50
51
notifyAll(); // tell waiting thread(s) to enter runnable state
52
53
return buffer;
54
} // end method blockingGet; releases lock on SynchronizedBuffer
55
56
// display current operation and buffer state; for demo only
57
private
synchronized
void displayState(String operation)
58
{
59
System.out.printf( "%-40s%d\t\t%b%n%n" , operation, buffer,
60
occupied);
61
}
62
} // end class SynchronizedBuffer
Fig. 23.16 | Synchronizing access to shared mutable data using Object methods wait and
notifyAll . (Part 2 of 2.)
Fields and Methods of Class SynchronizedBuffer
Class SynchronizedBuffer contains fields buffer (line 6) and occupied (line 7)—you
must synchronize access to both fields to ensure that class SynchronizedBuffer is thread
safe. Methods blockingPut (lines 10-31) and blockingGet (lines 34-54) are declared as
synchronized —only one thread can call either of these methods at a time on a particular
SynchronizedBuffer object. Field occupied is used to determine whether it's the Produc-
er 's or the Consumer 's turn to perform a task. This field is used in conditional expressions
in both the blockingPut and blockingGet methods. If occupied is false , then buffer is
empty, so the Consumer cannot read the value of buffer , but the Producer can place a val-
ue into buffer . If occupied is true , the Consumer can read a value from buffer , but the
Producer cannot place a value into buffer .
Method blockingPut and the Producer Thread
When the Producer thread's run method invokes synchronized method blockingPut ,
the thread implicitly attempts to acquire the SynchronizedBuffer object's monitor lock.
If the monitor lock is available, the Producer thread implicitly acquires the lock. Then the
loop at lines 14-20 first determines whether occupied is true . If so, buffer is full and we
want to wait until the buffer is empty, so line 17 outputs a message indicating that the
Producer thread is trying to write a value, and line 18 invokes method displayState
(lines 57-61) to output another message indicating that buffer is full and that the Pro-
ducer thread is waiting until there's space. Line 19 invokes method wait (inherited from
Object by SynchronizedBuffer ) to place the thread that called method blockingPut (i.e.,
the Producer thread) in the waiting state for the SynchronizedBuffer object. The call to
wait causes the calling thread to implicitly release the lock on the SynchronizedBuffer ob-
ject. This is important because the thread cannot currently perform its task and because
other threads (in this case, the Consumer ) should be allowed to access the object to allow
the condition ( occupied ) to change. Now another thread can attempt to acquire the Syn-
chronizedBuffer object's lock and invoke the object's blockingPut or blockingGet
method.
 
Search WWH ::




Custom Search