[concurrency-interest] concurrency puzzle

Jeremy Manson jmanson at cs.umd.edu
Sun Sep 10 17:37:00 EDT 2006


Peter Veentjer wrote:
>  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".
> If A was used by a single thread, this would be the case. But if A is
> used by multiple threads I'm not sure. This is the reason why double
> checked locking doesn't work for example:

We must be having some crossed communication lines somewhere, because I 
don't think we are talking about the same thing.  All I meant by the 
above was that this:

class A {
   int x = 10;
}

is the same as this:

class A {
   int x;
   public A() {
     x = 10;
   }
}

All javac does with the first is to turn it into the second.  It is 
relatively clear that this is the intention of the JLS, if you read 
Section 8.3.2.  It is what we intended when we wrote JSR-133.

None of this has anything to do with double-checked locking, which won't 
work regardless of whether the singleton object is constructed with its 
fields assigned in variable initializers or in a constructor.

So I'm pretty sure I'm not quite getting what you are saying.

> Let me create another example:
> 
> class B{
>   private int y = 10;
> 
>  public void print(){
>       System.out.println(y);
>  }
> }
> 
> What do you expect for output (if an instance of B also is used by
> different threads)
> 
> I would say 0 or 10.

If one thread constructs an object of type B, and passes a reference to 
that object to another thread via a data race, and that other thread 
invokes print(), then that print statement may emit either 0 or 10.

If, on the other hand, the print() method assigns a value to y before 
the println() statement, thus:

public void print() {
   y = 42;
   System.out.println(y);
}

then the same program would either print out 10 or 42, but not 0.  This 
is because the write of the value 0 to y is deemed to have taken place 
before the invocation of print().  In other words, the write of 0 to y 
is not in a data race with the accesses of y in the print method.  The 
write of 42 is considered to overwrite the value 0.

This is the intent of the fourth bullet point in Section 17.4.4 of the 
JLS, where we say "The write of the default value (zero, false or null) 
to each variable synchronizes-with the first action in every thread".

					Jeremy


More information about the Concurrency-interest mailing list