[concurrency-interest] synchronized constructors

√iktor Ҡlang viktor.klang at gmail.com
Mon Jan 16 11:55:05 EST 2012


2012/1/16 Ruslan Cheremin <cheremin at gmail.com>

> 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.
>

Now I remember that section, that's a great find. You just, as you say,
need to be careful of constant 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
> >
>



-- 
Viktor Klang

Akka Tech Lead
Typesafe <http://www.typesafe.com/> - The software stack for applications
that scale

Twitter: @viktorklang
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120116/d788e138/attachment-0001.html>


More information about the Concurrency-interest mailing list