[concurrency-interest] Volatile array and Wait
chris.purcell.39 at gmail.com
Wed Oct 19 13:34:33 EDT 2005
Okay, I've thought this out a bit. My analysis follows.
1) A volatile write should have the same semantics as a monitor release
2) A volatile read should have the same semantics as a monitor acquire
A monitor release ensures all preceding writes are visible before it
commits. A monitor acquire prevents subsequent read operations from
passing across it. These give the appearance of sequential execution of
We wish to attach release semantics to our write to b. Any
preceding writes must be visible to any reader who subsequently
performs an acquire.
If b is *followed* by a volatile write/monitor release, there is a
period of time in which concurrent updates may see the new value of
b but not any preceding writes despite performing an acquire in
between: namely, the time between the write to b committing and the
Unfortunately, if the write to b is *preceded* by a volatile
write/monitor release, the write to b can be moved before the
release barrier (either by compiler or hardware) since it is not itself
volatile; once again there is a period of time in which concurrent
updates may see the new value of b then do an acquire, yet still
not see any preceding writes, namely the time between the write to
b committing and the release barrier.
However, if one could precede the write to b with a release barrier
then a subsequent volatile read of a value on which the write operation
is dependent, then the write can no longer be reordered before the
barrier. The read of b should be sufficient for this.
Hence the correct code is:
b = b; // Release barrier
b = x; // Subsequent acquire barrier followed by dependent write
as I suggested.
Attaching a monitor acquire to the read of b is more problematic.
The acquire barrier must occur *after* the read of b to prevent
subsequent reads from being reordered incorrectly. To do this, one must
make the acquire barrier *dependent* on the read of b, or risk them
being reordered. In assembler, this would be trivial, as one could fake
a volatile read that was dependent on the value of b. I'm not clear
how to do this reliably in Java, as fake dependencies risk being
optimised away. The following might work, but might not:
x = b;
if (x < 1000)
temp = b;
temp = some_other_volatile;
In conclusion, don't try and emulate volatility.
More information about the Concurrency-interest