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

Vitaly Davidovich vitalyd at gmail.com
Wed Oct 3 12:59:00 EDT 2012

Calling Thread.start() ensures that the new thread sees all writes done by
the thread calling start() - this is documented/spec'd behavior.

However, I think what you're really asking is how final fields ensure
unsafe publishing works? Suppose you have two threads, W and R.  W
constructs some object with final fields and then stores this into a shared
static field.  R just spins doing the following:
Foo f = null;
while ((f = static_field) == null);
// f is not null here
int x = f.x; // some read of f

What final ensures is that if f is observed as not being null, then the
stores done inside the constructor are visible.

Let's leave theoretical pathology aside (e.g. it's a preemptive OS
scheduler, CPU store buffer drains at some point in time, etc).  In this
case, R will eventually read non-null as the write in W drains out of the
store buffer into L1 (assuming it was put into store buffer in the first
place).  At that point, normal cache coherency protocol takes care of R
seeing the writes - the question then is in what order were the writes made
visible by the CPU/core that W was running on.  On x86/64, the CPU does not
reorder stores - they are visible in execution order; this means we need to
ensure the compiler didn't move code around such that writes got
reordered.  On weaker memory models (e.g. arm, ppc) that do allow store
reordering, the jit has to not just avoid code motion but also emit
appropriate fence instructions.  This means on x86/64 final field store is
just a compiler fence - no CPU fence instructions needed.  On arm/ppc
though, fence instructions are needed.

Sent from my phone
On Oct 3, 2012 12:31 PM, "Andy Nuss" <andrew_nuss at yahoo.com> wrote:

> A simple way of asking, if thread (that receives the immutable wrapper)
> runs on a different cpu, then without a memory fence, how does it "see" the
> data?  Do constructors hide a memory fence instruction under the covers?
>   ------------------------------
> *From:* Andy Nuss <andrew_nuss at yahoo.com>
> *To:* "concurrency-interest at cs.oswego.edu" <
> concurrency-interest at cs.oswego.edu>
> *Sent:* Wednesday, October 3, 2012 9:22 AM
> *Subject:* Re: [concurrency-interest] do constructors ever involve
> threading under the covers?
> This does help.
> My model is this, and does involve multiple threads.  One thread creates
> and fills container data structure(s) that has no immutable guarantees,
> such as an ArrayList, HashMap, etc.  Then in that same thread, it calls a
> constructor to wrap the container, and give it an immutable api.  Then, the
> hope is that absolutely anyway that any other thread obtains a reference to
> the immutable wrapper, it will "see" all the data in the non-immutable
> containers.  Yes, I hope to not have to make defensive copies!  Yes, the
> same thread that seeded the data into non-thread safe containers is the
> thread that passes those containers to the immutable wrapper.
> I understand now that all I have to do is assign my argument containers to
> a final member references in the immutable wrapper.  And that if I do
> defensive copy, do it first, and assign to the final member references at
> the end.
> What I don't understand is this: another thread picks up the reference and
> starts using the object.  In all of the above, there was never a volatile
> member involved to ensure that other threads picking up the reference see
> the data in the containers.  Say I do this: new
> SomeThread(immutableReference).start().  This is the beginning of the
> second thread.  What is it about the final references in the immutable
> wrapper that causes SomeThread to "see" that data that Thread A seeded in
> ArrayList/HashMap and then wrapped in immutable wrapper, especially if
> there was no defensive copy?
> Once I understand this, then I'll understand the workings of String, which
> clearly have no volatile members.  Strings assume that the thread which
> seeded the char[] is the thread that constructs the String, and somehow
> without any use of volatile, other threads that pick up the reference to
> the constructed String "see" the data in the defensively copyied char[].
> "final" appears to solve reordering problems within the thread, but how
> does it "publish" data?
>   ------------------------------
> *From:* Jacy Odin Grannis <jacyg at alumni.rice.edu>
> *To:* Andy Nuss <andrew_nuss at yahoo.com>
> *Cc:* "concurrency-interest at cs.oswego.edu" <
> concurrency-interest at cs.oswego.edu>
> *Sent:* Wednesday, October 3, 2012 8:45 AM
> *Subject:* Re: [concurrency-interest] do constructors ever involve
> threading under the covers?
> I think there are two streams of thought here that are getting crossed.
> First, I agree with Vitaly that it's still unclear if you have
> multi-threading going on at all.  In the example you provide, is the
> EffectivelyImmutableArrayListWrapper used across multiple threads?  If
> it's not, than there's no need for really any modifier.  For a single
> thread, you never have to worry about reordering.  It might likely
> happen, but you are guaranteed that, going by program order,
> operations which happen 'before' will be done prior to their use.  So
> if the Wrapper is constructed and used within a single thread, you
> don't need volatile, or final, or even to create a copy at all if the
> 'list' arg is never going to be modified subsequent to wrapping.
> Second, based on the snipped below, if you *do* have multiple threads,
> which surely you must?  then the areas for concern would be how the
> 'list' arg is passed in (i.e., is it getting populated in another
> thread?) and then how the Wrapper is used after construction.  So
> let's address those:
> the list arg that you are passing in:  if it comes from the same
> thread, you're in the single thread situation and
> concurrency/reordering isn't an issue *up to the point of calling the
> constructor*.  However, if you are populating the list in a different
> thread before passing in, you need to make sure you pass/populate the
> list in a thread safe fashion.  Otherwise, writes from the populating
> thread might not have been done in the list when the Wrapper
> constructing thread does its thing.
> use of the wrapper:  if the wrapper will be used in the same thread it
> was constructed in, then you're in the single thread scenario.  If it
> will be used by multiple threads, then you have to worry about how you
> construct it.  If the list arg you are passing in is not referenced by
> any other threads and isn't going to be updated anywhere else, you
> don't need to create a deep copy.  You can simply assign it to a final
> variable, and you are good to go.  String(char[]) creates a defensive
> copy to *guarantee* that the contents won't change (it doesn't trust
> that you'll behave and drop your reference to the char[] you pass in).
> But creating a defensive copy is only necessary if you don't have
> control over who might invoke the constructor.  If you are going to
> create a defensive copy, your best bet would be to create the copy,
> then assign the fully populated copy to a final variable.  Assigning
> an empty copy to a volatile variable and then populating it doesn't
> work.  The volatile only applies to that reference, not to the
> references maintained inside the list itself.  You could create a
> fully populated copy and then assign to a volatile variable, but if
> you don't plan to change that reference, final would be a much better
> option.
> Does that help?
> jacy
> On Wed, Oct 3, 2012 at 9:37 AM, Andy Nuss <andrew_nuss at yahoo.com> wrote:
> > For clarification, lets say a caller passes my constructor an ArrayList
> with
> > seeded values.
> >
> > class EffectivelyImmutableArrayListWrapper {
> >    private volatile ArrayList  mylist;
> >    EffectivelyImmutableArrayListWrapper (ArrayList list)
> >    {
> >          // .... create mylist and copy all values from list into mylist
> >          // this class only provides getters for mylist
> >          // mylist never changes except in this constructor where created
> > and filled
> >    }
> >
> >    // getter functions for mylist
> > }
> >
> > From the above snippet, we see that we are attempting to provide a
> > publishing wrapper/snapshot for an ArrayList.  Is "volatile" necessary
> here?
> > I assume that "final" does not work, because "mylist" is just a
> reference.
> > Also, what if the contract of the constructor was that the caller would
> > never change/use the arraylist arg after calling the constructor: in that
> > case, could the constructor just copy the arg reference to the volatile
> > "mylist" member and be done?
> >
> > Assuming that I am correct that "mylist" has to be volatile, how does
> > java.lang.String accomplish immutability of the private char[] without
> > making it volatile?
> >
> > ________________________________
> > From: Andy Nuss <andrew_nuss at yahoo.com>
> > To: "concurrency-interest at cs.oswego.edu"
> > <concurrency-interest at cs.oswego.edu>
> > Sent: Wednesday, October 3, 2012 7:22 AM
> >
> > Subject: Re: [concurrency-interest] do constructors ever involve
> threading
> > under the covers?
> >
> > (It was a reply accident that I did not reply to list.)
> >
> > So if I follow you correctly, for a constructor that has an array or
> > ArrayList member, creates that array/ArrayList, and fills it with a
> bunch of
> > seeded values, which are effectively final: another thread will not see
> the
> > values in the array/ArrayList unless the constructed object is
> "published"
> > to the other thread, such as with a volatile variable or concurrent map.
> >
> > In that case, can someone explain to me how java String, which holds an
> > array of characters, is threadsafe without the need for publishing the
> > string to the other thread?  I.e. even if the array reference is final,
> the
> > "final" attribute does not apply to the elements of the array.  Same
> with a
> > final ArrayList reference.
> >
> > ________________________________
> > From: Aleksey Shipilev <aleksey.shipilev at oracle.com>
> > To: Andy Nuss <andrew_nuss at yahoo.com>
> > Sent: Wednesday, October 3, 2012 7:11 AM
> > Subject: Re: [concurrency-interest] do constructors ever involve
> threading
> > under the covers?
> >
> > Any specific reason you are not replying to the list? :)
> >
> > On 10/03/2012 06:04 PM, Andy Nuss wrote:
> >> The reason I ask about the constructor is this: java memory model
> >> provides a guarantee that all memory set/changed in the constructor is
> >> immediately visible to any other thread (that receives a reference to
> >> new object) after the constructor returns.  Is this true?
> >
> > Ughm, there is a requirement for the final field values of newly
> > constructed objects set in constructor are visible after constructor
> > finishes, and only in the case if you haven't leaked the reference to
> > "this" in the constructor.
> >
> > There is no memory semantics for constructor invocation otherwise. I.e.:
> >
> > class A {
> >  private int myField;
> >
> >  public int get() {
> >      // DOES NOT force $myField visibility
> >      return new A(myField).value;
> >  }
> > }
> >
> > class B {
> >  int v;
> >  public B(int v) { value = v; }
> > }
> >
> > Neither it would change if you make B.v final.
> >
> >> Is the contructor always executed in the same thread as its caller?
> >
> > Yes, it acts like ordinary method in this regard, no specific treatment.
> >
> > -Aleksey.
> >
> >
> >
> >
> >
> >
> >
> > _______________________________________________
> > 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/087b67b3/attachment-0001.html>

More information about the Concurrency-interest mailing list