Java Reference
In-Depth Information
reads each value produced once and only once, the total will be 55. However, if you exe-
cute this program several times, you'll see that the total is not always 55 (as shown in the
outputs in Fig. 23.13). To emphasize the point, the producer and consumer threads in the
example each sleep for random intervals of up to three seconds between performing their
tasks. Thus, we do not know when the producer thread will attempt to write a new value,
or when the consumer thread will attempt to read a value.
Interface Buffer
The program consists of interface Buffer (Fig. 23.9) and classes Producer (Fig. 23.10),
Consumer (Fig. 23.11), UnsynchronizedBuffer (Fig. 23.12) and SharedBufferTest
(Fig. 23.13). Interface Buffer (Fig. 23.9) declares methods blockingPut (line 6) and
blockingGet (line 9) that a Buffer (such as UnsynchronizedBuffer ) must implement to
enable the Producer thread to place a value in the Buffer and the Consumer thread to re-
trieve a value from the Buffer , respectively. In subsequent examples, methods blocking-
Put and blockingGet will call methods that throw InterruptedException s—typically
this indicates that a method temporarily could be blocked from performing a task. We de-
clare each method with a throws clause here so that we don't have to modify this interface
for the later examples.
1
// Fig. 23.9: Buffer.java
2
// Buffer interface specifies methods called by Producer and Consumer.
3
public interface Buffer
4
{
5
// place int value into Buffer
6
public void blockingPut( int value) throws InterruptedException;
7
8
// return int value from Buffer
9
public int blockingGet() throws InterruptedException;
10
} // end interface Buffer
Fig. 23.9 | Buffer interface specifies methods called by Producer and Consumer . ( Caution:
The example of Figs. 23.9-23.13 is not thread safe.)
Class Producer
Class Producer (Fig. 23.10) implements the Runnable interface, allowing it to be executed
as a task in a separate thread. The constructor (lines 11-14) initializes the Buffer reference
sharedLocation with an object created in main (line 15 of Fig. 23.13) and passed to the con-
structor. As we'll see, this is an UnsynchronizedBuffer object that implements interface
Buffer without synchronizing access to the shared object . The Producer thread in this program
executes the tasks specified in the method run (Fig. 23.10, lines 17-39). Each iteration of
the loop (lines 21-35) invokes Thread method sleep (line 25) to place the Producer thread
into the timed waiting state for a random time interval between 0 and 3 seconds. When the
thread awakens, line 26 passes the value of control variable count to the Buffer object's
blockingPut method to set the shared buffer's value. Lines 27-28 keep a total of all the val-
ues produced so far and output that value. When the loop completes, lines 36-37 display a
message indicating that the Producer has finished producing data and is terminating. Next,
method run terminates, which indicates that the Producer completed its task. Any method
called from a Runnable 's run method (e.g., Buffer method blockingPut ) executes as part
 
Search WWH ::




Custom Search