[concurrency-interest] synchronized constructors

Vitaly Davidovich vitalyd at gmail.com
Sat Dec 17 01:32:18 EST 2011


It cannot.  Let me try to explain ...

If we inline the constructor, then that sequence looks like this:
Vector tmp = alloc();
lock(tmp);
// some state initialization here ...
unlock(tmp);
v = tmp;

By roach motel semantics, v = tmp is a normal write, so it can move inside
the critical section.  lock(), however, has volatile read like semantics,
which means nothing after it can move before it, so we know v = tmp cannot
move above lock(), so it stays somewhere inside the critical section.  So
now we have two outcomes:

1.  v = tmp moved inside the critical section
2.  v = tmp stayed after the lock was released

Since Vector.add() is synchronized on itself, if #1 happens, add() blocks
and once it acquires the lock, it's guaranteed to see the writes.  If #2
happens, it's fine too since that's your regular lock scenario.

On Sat, Dec 17, 2011 at 12:11 AM, Zhong Yu <zhong.j.yu at gmail.com> wrote:

> 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, 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
> >
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>



-- 
Vitaly
617-548-7007 (mobile)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111217/765dc043/attachment.html>


More information about the Concurrency-interest mailing list