Java Reference
In-Depth Information
build a bounded buffer yourself. Again, using an
ArrayBlockingQueue
will result in more-
maintainable and better-performing code. In Exercise 23.13, we ask you to reimplement this
section's example, using the Java Concurrency API techniques presented in Section 23.9.
Implementing Your Own Bounded Buffer as a Circular Buffer
The program in Figs. 23.18 and 23.19 demonstrates a
Producer
and a
Consumer
accessing
a
bounded buffer with synchronization
. Again, we reuse interface
Buffer
and classes
Pro-
ducer
and
Consumer
from the example in Section 23.5, except that line 28 is removed
from class
Producer
and class
Consumer
. We implement the bounded buffer in class
Cir-
cularBuffer
(Fig. 23.18) as a
circular buffer
that uses a shared array of three elements. A
circular buffer writes into and reads from the array elements in order, beginning at the first
cell and moving toward the last. When a
Producer
or
Consumer
reaches the last element,
it returns to the first and begins writing or reading, respectively, from there. In this version
of the producer/consumer relationship, the
Consumer
consumes a value only when the ar-
ray is not empty and the
Producer
produces a value only when the array is not full. Once
again, the output statements used in this class's
synchronized
methods are for
demonstra-
tion purposes only
.
1
// Fig. 23.18: CircularBuffer.java
2
// Synchronizing access to a shared three-element bounded buffer.
3
public
class
CircularBuffer
implements
Buffer
4
{
5
private
final
int
[] buffer = {
-1
,
-1
,
-1
};
// shared buffer
6
7
private
int
occupiedCells =
0
;
// count number of buffers used
8
private
int
writeIndex =
0
;
// index of next element to write to
9
private
int
readIndex =
0
;
// index of next element to read
10
11
// place value into buffer
12
public
synchronized
void
blockingPut(
int
value)
throws
InterruptedException
13
14
{
15
// wait until buffer has space available, then write value;
16
// while no empty locations, place thread in blocked state
while
(occupiedCells == buffer.length)
{
System.out.printf(
"Buffer is full. Producer waits.%n")
;
wait();
// wait until a buffer cell is free
}
// end while
17
18
19
20
21
22
23
buffer[writeIndex] = value;
// set new buffer value
24
25
// update circular write index
26
writeIndex = (writeIndex +
1
) % buffer.length;
27
28
++occupiedCells;
// one more buffer cell is full
29
displayState(
"Producer writes "
+ value);
30
notifyAll();
// notify threads waiting to read from buffer
31
}
Fig. 23.18
|
Synchronizing access to a shared three-element bounded buffer. (Part 1 of 3.)