[concurrency-interest] concurrency puzzle
Jeremy Manson
jmanson at cs.umd.edu
Sun Sep 10 14:50:13 EDT 2006
Peter Veentjer wrote:
> On 9/10/06, Jeremy Manson <jmanson at cs.umd.edu> wrote:
>> Then it will either print 20 or 10. It can't print 0 because the write
>> of the default value (conceptually) happens-before the first action of
>> every thread.
> I was not sure about this one. I thought the following would happen
> 1) a stackframe is allocated with all defaults for the fields (x=0)
> 2) the initilization for the fields is called (so the x=10)
> 3) constructor call
[snip]
> I have been looking through the documentation, but the initialisation
> (x=10) felt the same as a constructor.
The initialization is the same as the constructor. If you look at the
bytecode generated by javac, you will see that field initializers
actually occur in the object's constructor. That was what I meant in my
previous message, when I said, "the write of 10 to x happens in the
constructor, according to the semantics of the Java programming
language".
Having said that, the fact that print() can't write out 0 has nothing to
do with the constructing thread. Basically, there is a conceptual write
of 0 to x that happens-before every other action in the program, at "The
Dawn of Time" (this corresponds to the GC zeroing out memory). Your
program can be abstracted in the following way:
"The Dawn of Time":
// zeroes out all memory, including:
f.x = 0;
Thread 1:
// The dawn of time happens-before this:
f.x = 10;
global.a = f;
Thread 2:
// The dawn of time happens-before this:
g = global.a;
g.x = 20;
print(g.x);
The execution engine for Thread 2 will know that the write of 20 has
overwritten the write of 0, because it knows that the write of 0
occurred at the dawn of time. It won't print 0.
What you said about Thread 1 is true in general, though: the accesses in
Thread 1 can be reordered, so that the write to f.x may not be visible
to Thread 2 when it performs its print.
I hope that is a little clearer than my last message. It is longer, any
way. :)
>> I'm not sure which JMM documentation you have been examining, if it
>> talks about local memory and invalidation. The old one had kind-of a
>> notion of local memory, but it hasn't been the "active" JMM for a good
>> while. Certainly, that JMM didn't talk about safe publication.
> JSR133, JCIP and Concurrent and Realtime programming in Java.
JSR 133, which is the official definition, doesn't make mention of local
memory or invalidation. If JCiP does (I don't remember), it is only to
explain the concepts of the official memory model.
> Instruction reordering makes it possible to see a partially constructed
> object
Yes. This is why there are additional semantics for final fields. If x
were final, even though there would be no write of 20, it would be
impossible for Thread 2 to print 0. This is because the correctly
constructed value of the final field is guaranteed to be seen regardless
of data races, cache effects and instruction reordering.
Jeremy
More information about the Concurrency-interest
mailing list