[concurrency-interest] synchronized constructors
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();
// some state initialization here ...
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;
> 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>
> > 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
> > is if a super class constructor does the unsafe publishing. But in that
> > 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
> > then no external user of the class can publish a reference in a way that
> > unsafe. If the constructor does the publishing within the synchronized
> > block, it is still safe. Only if the superclass does it can it possibly
> > unsafe.
> > Also to address an other point: lock elision is allowed (eg using escape
> > analysis) but the memory synchronization effects must remain (you can
> > 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
> > super constructor.
> > End of story :)
> > Cheers,
> > David
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Concurrency-interest