[concurrency-interest] synchronized constructors

Yuval Shavit yshavit at akiban.com
Fri Dec 16 22:51:31 EST 2011


I think you can ensure the ctor has finished even in the face of the
unsafest of unsafe sharing, just not with a synchronized block -- you just
need to set some sort of barrier. A CountDownLatch would do it, but
probably simpler would be a volatile boolean isInitialized. Set that to
true as the last action of your constructor, and check that it's true as
the first action of every subsequent method. I wonder if this would be an
appropriate time for a spin -- while (!isInitialized) {} -- since you
expect that in 99.9% of cases you'll loop 0 times, and in that rare case of
a safely unpublished reference being reordered relative to the constructor,
you might spin once or twice.

Of course, to do that, you would have to check isInitialized at the start
of *every* method. That implies your class (or at least all its method) has
to be final, or subclasses could easily break that invariant.

On Fri, Dec 16, 2011 at 8: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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111216/d8255a5d/attachment-0001.html>


More information about the Concurrency-interest mailing list