Java Reference
In-Depth Information
2. Inside of that synchronized method, the consumer calls
wait()
because
writeable
containstrue.Theconsumernowwaitsuntilitreceivesnotifica-
tion from the producer.
3. The producer eventually executes
s.setSharedChar(ch);
.
4. Whentheproducerentersthatsynchronizedmethod(whichispossiblebecause
theconsumerreleasedthelockinsideofthe
wait()
methodpriortowaiting),
the producer discovers
writeable
's value to be true and does not call
wait()
.
5. The producer saves the character, sets
writeable
to
false
(which will
causetheproducertowaitonthenext
setSharedChar()
callwhenthecon-
sumer has not consumed the character by that time), and calls
notify()
to
awaken the consumer (assuming the consumer is waiting).
6. The producer exits
setSharedChar(char c)
.
7. Theconsumerwakesup(andreacquiresthelock),sets
writeable
to
true
(whichwillcausetheconsumertowaitonthenext
getSharedChar()
call
whentheproducerhasnotproducedacharacterbythattime),notifiesthepro-
ducertoawakenthatthread(assumingtheproduceriswaiting),andreturnsthe
shared character.
Although the synchronization works correctly, you might observe output (on some
platforms) that shows multiple producing messages before a consuming message. For
example,youmightsee
A produced by producer.
,followedby
B produced
by producer.
,followedby
A consumed by consumer.
,atthebeginningof
the application's output.
Thisstrangeoutputorderiscausedbythecallto
setSharedChar()
followedby
its companion
System.out.println()
method call not being atomic, and by the
callto
getSharedChar()
followedbyitscompanion
System.out.println()
method call not being atomic. The output order is corrected by wrapping each of
these method call pairs in a synchronized block that synchronizes on the
s
-referenced
Shared
object.
Whenyourunthisapplication,itsoutputshouldalwaysappearinthesamealternating
order, as shown next (only the first few lines are shown for brevity):
A produced by producer.
A consumed by consumer.
B produced by producer.
B consumed by consumer.