[concurrency-interest] synchronized constructors

David Holmes davidcholmes at aapt.net.au
Sat Dec 17 03:49:30 EST 2011


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