[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