Re: what the benefit is by using annotation, like "@Immutable" ?
On Sun, 18 Jul 2010, Lew wrote:
Yes. Don't omit what tom said about /happens-before/:
In fact, it's worse than that. Thread A could finish the method and
update both calculated and code, but because there is no
happens-before relationship between thread A and thread B, it's
possible that B could come along later, and see the updated
calculated but *not* the updated code. So even without an unlucky
timeslice end, there is no guarantee of safety here.
Andreas Leitgeb wrote:
There is still a misunderstanding - I'm just not sure if it's on my or
your side. Thread 1 assigns two plain word-sized fields: a and then b.
can Thread 2 happen to see b's new value, and (after that) a's old
Tom's explanation was (as far as I understood it) based on the
code-sample where the flag was set before the code, and he rightly
pointed out that this gap may be even much longer than expected. Can
it reverse, as well?
When thread A changes values for shared data 'a' and 'b' without
establishment of /happens-before/, at some later time (even
chronologically after both values were changed), a different thread B
can examine those data and find any of four states: the old value for
both 'a' and 'b', the old value for 'a' and new for 'b', the new value
for 'a' and old for 'b', or the new value for both.
The situation that i imagine that could give rise to this is based on
caches. Imagine a two-processor system where the processors have
write-back caches and a miserable lack of cache coherency. Let's say that
cache lines are 16 bytes long, aligned on 16-byte boundaries. Let's say
there is an object containing two integer fields which starts at address
4: the two-word header occupies bytes 4-11, the first field is 12-15, and
the second is 16-20. The two words are thus on different cache lines. A
thread running on one processor updates both words of this object: these
updates go to the cache, but not yet to memory. Later, for some reason, it
evicts the cache line covering bytes 16-31, and writes it back to main
memory. The second processor now runs a thread which loads both fields,
neither being in its cache at that time; it will load the recently-written
version of the second line, but will get the version of the first line
that existed before the first processor did its write, which has not yet
been written back to memory.
I don't think there are any modern architectures where this can happen
(they all have cache coherency protocols to prevent it), but it's
admissible under the Java memory model.
YOUR MIND IS A NIGHTMARE THAT HAS BEEN EATING YOU: NOW EAT YOUR MIND. --
Kathy Acker, Empire of the Senseless