Java Reference
In-Depth Information
Line 23 in method blockingPut calls method lock on the SynchronizedBuffer 's
accessLock . If the lock is available (i.e., no other thread has acquired it), this thread now
owns the lock and the thread continues. If the lock is unavailable (i.e., it's held by another
thread), method lock waits until the lock is released. After the lock is acquired, lines 26-
46 execute. Line 29 tests occupied to determine whether buffer is full. If it is, lines 31-
32 display a message indicating that the thread will wait . Line 33 calls Condition method
await on the canWrite condition object, which temporarily releases the Synchronized-
Buffer 's Lock and waits for a signal from the Consumer that buffer is available for writing.
When buffer is available, the method proceeds, writing to buffer (line 36), setting occu-
pied to true (line 40) and displaying a message indicating that the producer wrote a value
(line 42). Line 45 calls Condition method signal on condition object canRead to notify
the waiting Consumer (if there is one) that the buffer has new data to be read. Line 49 calls
method unlock from a finally block to release the lock and allow the Consumer to pro-
ceed.
Line 57 of method blockingGet (lines 54-86) calls method lock to acquire the Lock .
This method waits until the Lock is available . Once the Lock is acquired , line 63 tests
whether occupied is false , indicating that the buffer is empty . If so, line 67 calls method
await on condition object canRead . Recall that method signal is called on variable can-
Read in the blockingPut method (line 45). When the Condition object is signaled , the
blockingGet method continues. Lines 72-74 set occupied to false , store the value of
buffer in readValue and output the readValue . Then line 78 signals the condition object
canWrite . This awakens the Producer if it's indeed waiting for the buffer to be emptied .
Line 82 calls method unlock from a finally block to release the lock, and line 85 returns
readValue to the caller.
Common Programming Error 23.3
Forgetting to signal a waiting thread is a logic error. The thread will remain in the wait-
ing state, which will prevent it from proceeding. Such waiting can lead to indefinite post-
ponement or deadlock.
Class SharedBufferTest2
Class SharedBufferTest2 (Fig. 23.21) is identical to that of Fig. 23.17. Study the outputs
in Fig. 23.21. Observe that every integer produced is consumed exactly onceā€”no values are
lost, and no values are consumed more than once. The Lock and Condition objects ensure
that the Producer and Consumer cannot perform their tasks unless it's their turn. The Pro-
ducer must go first, the Consumer must wait if the Producer has not produced since the
Consumer last consumed and the Producer must wait if the Consumer has not yet con-
sumed the value that the Producer most recently produced. Execute this program several
times to confirm that every integer produced is consumed exactly once. In the sample out-
put, note the highlighted lines indicating when the Producer and Consumer must wait to
perform their respective tasks.
1
// Fig. 23.21: SharedBufferTest2.java
2
// Two threads manipulating a synchronized buffer.
3
import java.util.concurrent.ExecutorService;
Fig. 23.21 | Two threads manipulating a synchronized buffer. (Part 1 of 3.)
 
Search WWH ::




Custom Search