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

Zhong Yu zhong.j.yu at gmail.com
Wed Oct 3 15:32:49 EDT 2012


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


More information about the Concurrency-interest mailing list