Java Reference
In-Depth Information
We Call
Thread
Method
sleep
Only for Demonstration Purposes
We call method
sleep
in method
run
of the
Producer
and
Consumer
classes to emphasize
the fact that,
in multithreaded applications, it's unpredictable when each thread will perform
its task and for how long it will perform the task when it has a processor
. Normally, these
thread scheduling issues are beyond the control of the Java developer. In this program, our
thread's tasks are quite simple—the
Producer
writes the values
1
to
10
to the buffer, and
the
Consumer
reads 10 values from the buffer and adds each value to variable
sum
. Without
the
sleep
method call, and if the
Producer
executes first, given today's phenomenally fast
processors, the
Producer
would likely complete its task before the
Consumer
got a chance
to execute. If the
Consumer
executed first, it would likely consume garbage data ten times,
then terminate before the
Producer
could produce the first real value.
Class
UnsynchronizedBuffer
Does Not Synchronize Access to the Buffer
Class
UnsynchronizedBuffer
(Fig. 23.12) implements interface
Buffer
(line 4), but does
not
synchronize access to the buffer's state—we purposely do this to demonstrate the prob-
lems that occur when multiple threads access
shared mutable data
in
without
synchroniza-
tion. Line 6 declares instance variable
buffer
and initializes it to
-1
. This value is used to
demonstrate the case in which the
Consumer
attempts to consume a value
before
the
Pro-
ducer
ever places a value in
buffer
. Again, methods
blockingPut
(lines 9-13) and
block-
ingGet
(lines 16-20) do
not
synchronize access to the
buffer
instance variable. Method
blockingPut
simply assigns its argument to
buffer
(line 12), and method
blockingGet
simply returns the value of
buffer
(line 19). As you'll see in Fig. 23.13,
Unsynchronized-
Buffer
object is shared between the
Producer
and the
Consumer
.
1
// Fig. 23.12: UnsynchronizedBuffer.java
2
// UnsynchronizedBuffer maintains the shared integer that is accessed by
3
// a producer thread and a consumer thread.
4
public
class
UnsynchronizedBuffer
implements
Buffer
5
{
6
private
int
buffer =
-1
;
// shared by producer and consumer threads
7
8
// place value into buffer
9
public
void
blockingPut(
int
value)
throws
InterruptedException
10
{
11
System.out.printf(
"Producer writes\t%2d"
, value);
12
buffer = value;
13
}
14
15
// return value from buffer
16
public
int
blockingGet()
throws
InterruptedException
17
{
18
System.out.printf(
"Consumer reads\t%2d"
, buffer);
19
return
buffer;
20
}
21
}
// end class UnsynchronizedBuffer
Fig. 23.12
|
UnsynchronizedBuffer
maintains the shared integer that is accessed by a producer
thread and a consumer thread. (
Caution:
The example of Fig. 23.9-Fig. 23.13 is
not
thread safe.)