Bill,
One situation I have wrestled with is that of an object that creates a 
thread (implemented as an inner class) from within the constructor. The 
created (inner-class) object cannot access the creating (outer-class) 
object reliably, since there's no memory barrier or synchronization. I've 
usually solved this problem by synchronizing the constructor [with a 
synchronized(this)] and then having the inner-class constructor synchronize 
using synchronized(Outer.this). The problem with this strategy is that the 
code that assigns a value to a field that's initialized in the declaration 
(which can take an initial value from the outer-class object) is not 
included in the synchronized block. On the other hand, it's quite intuitive 
how it works---the created thread is effectively suspended until the 
creating constructor exits the synchronized block. Your second proposal 
seems to solve this access-by-initializer problem, but synchronizing the 
constructor seems like a more intuitive solution. Perhaps the best solution 
is to support both mechanisms.
Allen
>Say you want to design a class Foo that is designed to work correctly, 
>even if references to Foo objects are passed between threads via a data 
>race (perhaps maliciously so). Strings are one example of a class we need 
>to have be race-proof.
>
>For immutable classes, we have a solution: use final fields. But what 
>about for mutable classes?
>
>The standard approach in such cases would be to simply synchronize all of 
>the methods of the class, but to not synchronize the constructor. 
>Syntactically, it is illegal to declare a constructor as synchronized. You 
>could fake it using a synchronized block inside the constructor, but I've 
>never seen code that does so.
>
>Unfortunately, to really make the class race-proof, you need to have the 
>constructor be synchronized. Without a synchronized constructor, there is 
>nothing that forces the processor that initializes the object to send the 
>initializing writes from its cache out to main memory.
>
>The JLS states (Section 8.8.3):
>
>"Unlike methods, a constructor cannot be abstract, static, final, native, 
>or synchronized.... There is no practical need for a constructor to be 
>synchronized, because it would lock the object under construction, which 
>is normally not made available to other threads until all constructors for 
>the object have completed their work. "
>
>Unfortunately, this is wrong (and has led to some confusion). While there 
>is no practical need in constructors for the mutual exclusion semantics of 
>synchronization, synchronization also has important visibility semantics 
>that are relevant for constructors.
>
>I see two possible solutions:
>
>* Say that in order to bullet-proof the class, you need to use synchronization
>   in constructors. You could do this through a synchronized block, but we 
> could
>   also change the language to allow synchronized constructors.
>
>   -- or --
>
>* Give constructors special visibility semantics: when a thread synchronizes
>   on an object, it sees all writes that were visible to the constructing 
> thread
>   at the time the object's constructor terminated. In other words, all
>   constructors have the visibility semantics of being synchronized, 
> without the
>   mutual exclusion semantics of being synchronized. Assuming that you 
> don't make
>   objects visible to other threads until after they are constructed, this is
>   essentially the same as synchronizing all constructors.
>
>Given these choices, I recommend the second option. Although either would 
>allow for the creation of race-proof classes, the first option would mean 
>that most/all existing synchronized classed would be broken, and I think 
>it would be very hard to get most programmers to understand why and when 
>constructors need to be synchronized. I don't think choosing the second 
>option would require more memory barriers; for a number of reasons, we 
>probably already need a memory barrier at the end of each constructor on 
>processors with weak memory models.
>
>Thoughts?
>
>         Bill
>-------------------------------
>JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
>
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:29 EDT