[concurrency-interest] synchronized constructors

Boehm, Hans hans.boehm at hp.com
Fri Dec 16 16:49:01 EST 2011


Just to be clear: Safe publication for final fields requires that you do not make a pointer to the object available to other threads (publish it) before the constructor finishes.  "Safe publication" as used below is a slightly stronger property; you also should not communicate the pointer post-construction to another thread via a data race.  Avoiding them both is great advice, but the second one may be difficult to avoid if you need to give a reference to your object to code you don't trust.  Malicious code could always pass the object to a third thread through a race, hoping that the third thread, which has no happens-before relationship to the other two, would find your object in an inconsistent state.  My intuition is that this is a rare case, but one that does occur.  When it does occur, the odds of an actual security hole are probably small, but so are the odds of proving security properties without addressing the issue.

Hans

From: concurrency-interest-bounces at cs.oswego.edu [mailto:concurrency-interest-bounces at cs.oswego.edu] On Behalf Of Yuval Shavit
Sent: Friday, December 16, 2011 11:59 AM
To: Zhong Yu
Cc: concurrency-interest at cs.oswego.edu
Subject: Re: [concurrency-interest] synchronized constructors

On Fri, Dec 16, 2011 at 2:10 PM, Zhong Yu <zhong.j.yu at gmail.com<mailto:zhong.j.yu at gmail.com>> wrote:
On Fri, Dec 16, 2011 at 8:38 AM, Yuval Shavit <yshavit at akiban.com<mailto:yshavit at akiban.com>> wrote:
> Several people have made the claim that you could see partially initialized
> state even if the constructor were synchronized, and I don't see how this
> could be. Yes, you could assign MyPoint myUnsafeRef before MyPoint()
> finishes -- but if you ever tried to *use* myUnsafeRef, you would run into a
> synchronized block which would then ensure that the constructor
> happened-before whatever method you're writing. Seems to me you should see
> the fully-thread-safe, not-partially-initialized object at that point.
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.

Ah yes, I hadn't thought of that.

So now, in order to have my class be over-achievingly thread safe, I need to replace my synchronized methods with a latch that waits for construction to finish and *then* a synchronized (this) {...}. But I probably decide that this is really going far out of my way to support a bad usage pattern, so I throw up my arms and say "you'll see either totally blank or post-initialization state, but not partial initialization."  But that means I have to guard against uninitialized state in each method, so I probably throw up my arms again and say "just publish the darn object safely!"  And then the JLS people come to me and say, "well if that's your requirement, why do you want a synchronized constructor?"  And suddenly the whole thing makes sense.

This has been an interesting discussion for me! Thanks everyone. :)

-Yuval
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111216/392e56d6/attachment-0001.html>


More information about the Concurrency-interest mailing list