[concurrency-interest] synchronized constructors

Ruslan Cheremin cheremin at gmail.com
Mon Jan 16 11:53:33 EST 2012


JSL 17.5.3, http://java.sun.com/docs/books/jls/third_edition/html/memory.html#60903

"In some cases, such as deserialization, the system will need to
change the final fields of an object after construction. Final fields
can be changed via reflection and other implementation dependent
means. The only pattern in which this has reasonable semantics is one
in which an object is constructed and then the final fields of the
object are updated. The object should not be made visible to other
threads, nor should the final fields be read, until all updates to the
final fields of the object are complete. Freezes of a final field
occur both at the end of the constructor in which the final field is
set, and immediately after each modification of a final field via
reflection or other special mechanism."

So it you do not publish reference, and do not read field which will
be modified -- you'll have "freeze" action after reflection-based
update of final field, which is the same as in the end of constructor.
It will look like you have long-long constructor, which finished just
here.

Just read carefully subsequent warnings in JLS, about setting final
field to compile time constant, which can be inlined by compiler.  It
seems like you should set initial f-field value to something, passed
from constructor -- to prevent inlining.

16 января 2012 г. 20:42 пользователь √iktor Ҡlang
<viktor.klang at gmail.com> написал:
>
>
> On Mon, Jan 16, 2012 at 5:33 PM, Ruslan Cheremin <cheremin at gmail.com> wrote:
>>
>> 2011/12/17 Roland Kuhn <rk at rkuhn.info>:
>> > You might ask, why have a non-final field without proper
>> > synchronization, so
>> > let me add that the background to this question is that in my case the
>> > construction of the object needs to proceed in two phases because of
>> > other
>> > inter-dependencies, which requires certain fields to be written to after
>> > the
>> > constructor has finished; they will be written to only exactly once, and
>> > this happens before “untrusted” client code obtains the reference (in
>> > program order).
>>
>> May be it's too late for this -- but you can still use final fields,
>> but update them via reflection. If you do not publish object reference
>> _before_ all reflection-based modifications finished -- you still have
>> all final fields guarantee. From you description it seems like it is
>> your case.
>>
>
> That's interesting, can you point me to the spec?
>
> Cheers,
>>
>
>>
>>
>> > Thanks in advance,
>> >
>> > Roland
>> >
>> > On Dec 16, 2011, at 22:49 , Boehm, Hans wrote:
>> >
>> > 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> wrote:
>> >
>> > On Fri, Dec 16, 2011 at 8:38 AM, Yuval Shavit <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
>> > _______________________________________________
>> > Concurrency-interest mailing list
>> > Concurrency-interest at cs.oswego.edu
>> > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>> >
>> >
>> > --
>> > [scala-debate on 2009/10/2]
>> > Viktor Klang: When will the days of numerical overflow be gone?
>> > Ricky Clarkson: One second after 03:14:07 UTC on Tuesday, 19 January
>> > 2038
>> >
>> >
>> > _______________________________________________
>> > Concurrency-interest mailing list
>> > Concurrency-interest at cs.oswego.edu
>> > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>> >
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
>
> --
> Viktor Klang
>
> Akka Tech Lead
> Typesafe - The software stack for applications that scale
>
> Twitter: @viktorklang
>



More information about the Concurrency-interest mailing list