[concurrency-interest] synchronized constructors

Zhong Yu zhong.j.yu at gmail.com
Sat Dec 17 04:47:17 EST 2011


You guys are totally right, thanks. I apologize, especially to Yuval.

For the execution I described to occur where blank state is observed
by thread 2, sync{} in thread 2 must be ordered before sync{} in
thread 1; this makes read(v) in thread 2 happens-before write(v) in
thread 1. The execution also has the read see the write. Therefore the
execution is not "happens-before consistent", therefore not
well-formed.

Zhong Yu

On Sat, Dec 17, 2011 at 2:49 AM, David Holmes <davidcholmes at aapt.net.au> wrote:
> Zhong Yu writes:
>> Suppose constructor java.util.Vector() is synchronized
>>
>>     static Vector v;
>>
>>     // thread 1
>>     v = new Vector();
>>
>>     // thread 2
>>     Vector r = v;
>>     if(r!=null)
>>       r.add(x);
>>
>> The last line can throw exception, because thread 2 can observe the
>> blank state of the object
>
> No it can not. Completion of the constructor happens-before the reference is
> published. The acquiring of the monitor in add() can only happen when the
> monitor is released by the constructor. The release of the monitor in thread
> 1 happens-before the acquire of the monitor by thread 2. All the constructor
> actions happen-before the release of the monitor.
>
> The publishing of the Vector can not be moved prior to the acquisition of
> the monitor in the constructor ("roach motel semantics").
>
> David
> -----
>
>
>> , yet Vector.add() presumes a> post-construction state.
>
>> Zhong Yu
>>
>> On Fri, Dec 16, 2011 at 7:52 PM, David Holmes
>> <davidcholmes at aapt.net.au> wrote:
>> > Zhong Yu writes:
>> >> If the reference is unsafely published, another thread can get the
>> >> reference early; it then calls an instance method which may obtain the
>> >> lock before the creation thread can obtain the lock for the
>> >> constructor. Therefore the other thread can observe the blank state.
>> >> As Ruslan corrected me, no partial state can be observed though.
>> >
>> > The only way this can happen, if you synchronize the whole
>> constructor body,
>> > is if a super class constructor does the unsafe publishing. But
>> in that case
>> > there is no such thing as safe-publishing because the object can escape
>> > before the subclass constructor does any initialization.
>> >
>> > To summarize a long and garbled thread. If the constructor body is
>> > synchronized, there is no accessible state and all methods are
>> synchronized,
>> > then no external user of the class can publish a reference in a
>> way that is
>> > unsafe. If the constructor does the publishing within the synchronized
>> > block, it is still safe. Only if the superclass does it can it
>> possibly be
>> > unsafe.
>> >
>> > Also to address an other point: lock elision is allowed (eg using escape
>> > analysis) but the memory synchronization effects must remain
>> (you can lose
>> > enforced mutual exclusion [as you don't need it], but not happens-before
>> > edges).
>> >
>> > Constructors can't be synchronized simply because back in 1995 no one
>> > realized there could be a need for it. It can be mostly worked around by
>> > using a synchronized block. But you can't synchronize the
>> invocation of the
>> > super constructor.
>> >
>> > End of story :)
>> >
>> > Cheers,
>> > David
>> >
>>
>



More information about the Concurrency-interest mailing list