Java Reference
In-Depth Information
It may appear that the result
r2 == 2
and
r1 == 1
is impossible. Intuitively, either instruc-
tion 1 or instruction 3 should come first in an execution. If instruction 1 comes first,
it should not be able to see the write at instruction 4. If instruction 3 comes first, it
should not be able to see the write at instruction 2.
If some execution exhibited this behavior, then we would know that instruction 4
came before instruction 1, which came before instruction 2, which came before in-
struction 3, which came before instruction 4. This is, on the face of it, absurd.
However, compilers are allowed to reorder the instructions in either thread, when this
does not affect the execution of that thread in isolation. If instruction 1 is reordered
with instruction 2, as shown in the trace in
Table 17.2
,
then it is easy to see how the
result
r2 == 2
and
r1 == 1
might occur.
Table 17.2. Surprising results caused by statement reordering - valid compiler trans-
formation
To some programmers, this behavior may seem “broken”. However, it should be noted
that this code is improperly synchronized:
• there is a write in one thread,
• a read of the same variable by another thread,
• and the write and read are not ordered by synchronization.
counterintuitive results are often possible.
Several mechanisms can produce the reordering in
Table 17.2
.
A Just-In-Time com-
piler in a Java Virtual Machine implementation may rearrange code, or the processor.
In addition, the memory hierarchy of the architecture on which a Java Virtual Machine
implementation is run may make it appear as if code is being reordered. In this
chapter, we shall refer to anything that can reorder code as a
compiler
.
p.x == 0
. This program is also incorrectly synchronized; it writes to shared memory
without enforcing any ordering between those writes.