[concurrency-interest] do constructors ever involve threading under the covers?

Vitaly Davidovich vitalyd at gmail.com
Wed Oct 3 16:10:19 EDT 2012


I think Yuval and you are right.  I just looked at the JLS and example
17.5-1 shows that the StoreStore barrier doesn't extend to end of
constructor automatically.  I guess the ThreeStooges.java example that
Aleksey linked to earlier works, despite the final assignment occurring
before the writes into the list, is because those writes are reachable via
the final field and thus get included in the freeze action.

Sent from my phone
On Oct 3, 2012 3:32 PM, "Zhong Yu" <zhong.j.yu at gmail.com> wrote:

> We may say a final field `f` protects an extended territory, anything
> reachable from `f` is in the territory. Any write (before constructor
> exit) into the territory cannot be reordered with publication of
> `this`. Other writes are not protected by this treaty. In Yuval's
> example, `a=1` can be reordered to an arbitrarily late place.
>
> On Wed, Oct 3, 2012 at 2:14 PM, Vitaly Davidovich <vitalyd at gmail.com>
> wrote:
> > Right, but that's a different matter since final assignment is
> specifically
> > the order between the final assignment in ctor and ref assignment rather
> > than other surrounding operations.
> >
> > Sent from my phone
> >
> > On Oct 3, 2012 3:09 PM, "Zhong Yu" <zhong.j.yu at gmail.com> wrote:
> >>
> >> I guess the spec is deliberately weakened, so that for example
> >>
> >>     anInt = 1;
> >>     anStr = new String(bytes);
> >>
> >> no ordering constraint is imposed; the 1st write can be reordered
> >> after the 2nd, passing the constructor with final field writes.
> >>
> >> This seems unnecessarily sophisticated; too much for mortals.
> >>
> >> On Wed, Oct 3, 2012 at 1:58 PM, Vitaly Davidovich <vitalyd at gmail.com>
> >> wrote:
> >> > This depends on what exactly is the scope of a final field assignment,
> >> > as
> >> > Aleksey and I have discussed here.  If the mere presence of a final
> >> > assignment in the ctor, irrespective of its order with other local
> >> > assignments, means there's a StoreStore barrier placed right before
> >> > shared
> >> > ref assignment, then the whole body of the ctor is visible if the
> shared
> >> > ref
> >> > is, and thus no such reordering can occur.
> >> >
> >> > If StoreStore is placed right after the final assignment only, then it
> >> > can.
> >> >
> >> > Sent from my phone
> >> >
> >> > On Oct 3, 2012 2:52 PM, "Zhong Yu" <zhong.j.yu at gmail.com> wrote:
> >> >>
> >> >> On Wed, Oct 3, 2012 at 1:44 PM, Vitaly Davidovich <vitalyd at gmail.com
> >
> >> >> wrote:
> >> >> > Final is stronger than volatile in terms of store operations inside
> >> >> > ctor
> >> >> > and
> >> >> > subsequent assignment to the ref, which happens to enable the racy
> >> >> > publication that still works; volatile wouldn't work.
> >> >> >
> >> >> > As for your example, it's not allowed.  In order for another thread
> >> >> > to
> >> >> > call
> >> >> > verify(), they must have seen a non-null reference.  We also know
> >> >> > that
> >> >> > final
> >> >> > assignment prevents reordering of ctor body with assignment to
> shared
> >> >> > ref.
> >> >>
> >> >> If the compiler can prove that a write in ctor is to a location that
> >> >> cannot be referenced through the final field, then the write can be
> >> >> reordered, even after the write to shared ref.
> >> >>
> >> >> Such proof is probably difficult; unless the field is primitive.
> >> >>
> >> >> > I think I agree with Aleksey in that any final assignment in the
> ctor
> >> >> > prevents the reordering.  Therefore, if thread sees non-null ref to
> >> >> > call
> >> >> > verify() on, it cannot see a == 0.
> >> >> >
> >> >> > Sent from my phone
> >> >> >
> >> >> > On Oct 3, 2012 1:51 PM, "Yuval Shavit" <yshavit at akiban.com> wrote:
> >> >> >>
> >> >> >> Is that true? I was under the impression that final only has
> memory
> >> >> >> visibility implications for the final field itself, and anything
> >> >> >> gotten
> >> >> >> from
> >> >> >> it. So for instance:
> >> >> >>
> >> >> >> class Foo {
> >> >> >>     int a;
> >> >> >>     final boolean ctorDone;
> >> >> >>
> >> >> >>     Foo() {
> >> >> >>         a = 1;
> >> >> >>         ctorDone = true;
> >> >> >>     }
> >> >> >>
> >> >> >>     void verify() {
> >> >> >>         while (!ctorDone) { /* spin */ }
> >> >> >>         assert a == 1 : a;
> >> >> >>     }
> >> >> >> }
> >> >> >>
> >> >> >> My understanding is that (assuming unsafe publication and all
> that)
> >> >> >> the
> >> >> >> JMM is allowed to have a == 0 in Foo.verify, because the memory
> >> >> >> visibility
> >> >> >> only applies to ctorDone. If ctorDone were a volatile, then
> reading
> >> >> >> it
> >> >> >> would
> >> >> >> ensure a full HB edge, and you'd be guaranteed to see a == 1.
> >> >> >>
> >> >> >> On Wed, Oct 3, 2012 at 1:32 PM, Zhong Yu <zhong.j.yu at gmail.com>
> >> >> >> wrote:
> >> >> >>>
> >> >> >>> We may say `final` is stronger than `volatile`, it has all the
> >> >> >>> semantics of `volatile', and more.
> >> >> >>>
> >> >> >>> `volatile` is not strong enough to build thread-safe immutable
> >> >> >>> objects, `final` is.
> >> >> >>>
> >> >> >>> On Wed, Oct 3, 2012 at 8:24 AM, Andy Nuss <andrew_nuss at yahoo.com
> >
> >> >> >>> wrote:
> >> >> >>> > Hi,
> >> >> >>> >
> >> >> >>> > I have a class with a single member, a reference to a new
> >> >> >>> > MessageDigest
> >> >> >>> > obtained in the constructor based on the algorithm name passed
> to
> >> >> >>> > the
> >> >> >>> > constructor.  The constructor also has a Reader argument and
> >> >> >>> > reads
> >> >> >>> > all
> >> >> >>> > the
> >> >> >>> > data from the Reader thru an OutputStreamWriter("UTF-8) and
> >> >> >>> > passes
> >> >> >>> > thru
> >> >> >>> > to
> >> >> >>> > the digest with my own OutputStream filter.  The call to the
> >> >> >>> > constructor
> >> >> >>> > then accesses the MessageDigest member and calls digest() to
> get
> >> >> >>> > the
> >> >> >>> > resulting byte[].  My code by all appearances is single
> threaded,
> >> >> >>> > but I
> >> >> >>> > am
> >> >> >>> > having strange bugs that on one particular machine running
> >> >> >>> > vmware,
> >> >> >>> > the
> >> >> >>> > digest result I am getting (for password hashing) appears not
> to
> >> >> >>> > be
> >> >> >>> > repeatable.
> >> >> >>> >
> >> >> >>> > Basically, I am wondering if another thread can execute the
> body
> >> >> >>> > of
> >> >> >>> > the
> >> >> >>> > constructor (or in the construction and use of the
> >> >> >>> > OutputStreamWriter,
> >> >> >>> > within my constructor) that could be causing a bug where memory
> >> >> >>> > written
> >> >> >>> > by
> >> >> >>> > the MessageDigest.update() function (triggered within the
> >> >> >>> > constructor
> >> >> >>> > by
> >> >> >>> > writing thru OutputStreamWriter) is not seen in the call to
> >> >> >>> > digest()
> >> >> >>> > on
> >> >> >>> > the
> >> >> >>> > newly created MessageDigest member after the constructor
> returns.
> >> >> >>> >
> >> >> >>> > Andy
> >> >> >>> >
> >> >> >>> > _______________________________________________
> >> >> >>> > 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
> >> >> >>
> >> >> >>
> >> >> >>
> >> >> >> _______________________________________________
> >> >> >> 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/20121003/3595ac20/attachment.html>


More information about the Concurrency-interest mailing list