Java Reference
In-Depth Information
thread used synchronization,
B
could possibly see
A
's actions in a different order than
A
per-
formed them. So even though
A
initialized the
Resource
before setting
resource
to ref-
erence it,
B
could see the write to
resource
as occurring
before
the writes to the fields of
the
Resource
.
B
could thus see a partially constructed
Resource
that may well be in an
invalid state—and whose state may unexpectedly change later.
With the exception of immutable objects, it is not safe to use an object that has been initial-
ized by another thread unless the publication
happens-before
the consuming thread uses it.
16.2.2. Safe Publication
The safe-publication idioms described in
Chapter 3
ensure that the published object is visible
to other threads because they ensure the publication happensbefore the consuming thread
loads a reference to the published object. If thread A places X on a BlockingQueue (and no
thread subsequently modifies it) and thread B retrieves it from the queue, B is guaranteed to
see X as A left it. This is because the BlockingQueue implementations have sufficient intern-
al synchronization to ensure that the put
happens-before
the take. Similarly, using a shared
variable guarded by a lock or a shared volatile variable ensures that reads and writes of that
variable are ordered by
happens-before
.
This
happens-before
guarantee is actually a stronger promise of visibility and ordering than
made by safe publication. When X is safely published from A to B, the safe publication guar-
antees visibility of the state of X, but not of the state of other variables A may have touched.
But if A putting X on a queue
happens-before
B fetches X from that queue, not only does B
see X in the state that A left it (assuming that X has not been subsequently modified by A
or anyone else), but B sees everything A did before the handoff (again, subject to the same
caveat).
[5]
Why did we focus so heavily on @GuardedBy and safe publication, when the JMM already
provides us with the more powerful
happens-before
? Thinking in terms of handing off object
ownership and publication fits better into most program designs than thinking in terms of
visibility of individual memory writes. The
happens-before
ordering operates at the level of
individual memory accesses—it is a sort of “concurrency assembly language”. Safe publica-
tion operates at a level closer to that of your program's design.