easiest way to force a write membar in jdk7 and 8

Andy Nuss andrew_nuss at yahoo.com
Sun Feb 22 16:54:47 UTC 2015


By the way, did you note that there are ongoing continuous stores into ar beyond the published range limit by the thread that owns the non-threadsafe version of the int[]?  Of course, thru private fields and public members, the idea is that up to a certain range boundary, there will be no additional stores possible.  I ask, because (1) I just wanted to make sure you were aware of that requirement of continuous additions permitted beyond the published range, and (2) I would have thought that a core contributor such as yourself would have been more sure than "I think" :-)
I googled hard and seemed to get StackOverflow experts saying that java.lang.String is immutable and threadsafe with just final fields principally because the internal "ar" is virgin to all threads as it is created in the String constructor, but obviously that approach is not good enough for me because of the unwanted buffer copy.  (Also, String is exposed thru JNI in a special way, and that might have an impact?)
I do also have the belief that in about 2004 or thereabouts (possibly around the time of JSR 133), it was no longer possible to create a String from a StringBuilder in O(1) time, so that scared me that my idea would *not* in fact work. 

     On Sunday, February 22, 2015 8:27 AM, Vitaly Davidovich <vitalyd at gmail.com> wrote:
   

 I think your scheme will work, even with just IntArray (i.e. don't need volatile) since the stores into the array cannot appear after the constructor of IntArray.  If another thread sees "ar" that's ok as they're seeing the reference to the base address of the array, which isn't changing.False sharing can create performance problem, not correctness.  Your first 8 array elements will take up 32 bytes of memory, which means they may share the cacheline with the elements of the subsequent range; as you write the values of the subsequent range, the reader of the previous range (assuming this happens in parallel) will have its cacheline invalidated.  This is probably not that big of a concern given your setup though, but did want to mention that just in case.  If you wanted to avoid this, you'd need to ensure the elements of the array belonging to a range are 1-2 cachelines away from each other.sent from my phoneOn Feb 22, 2015 11:11 AM, "Andy Nuss" <andrew_nuss at yahoo.com> wrote:

JDK7 and 8 only.
I was hoping that this scheme would work regardless of "how" the IntArray obtained from the publish() method was in turn itself passed to other threads.  Because I want to do this in a library.
What do you mean by false sharing?  Does my scheme not work?  If not, is there a scheme that does work?  In my mind, doesn't the JSR 133 indicate that this *must* work?
 

     On Sunday, February 22, 2015 8:03 AM, Vitaly Davidovich <vitalyd at gmail.com> wrote:
   

 What version of java is this for? How are you publishing to other threads exactly?By the way, you should keep in that you'll most likely get false sharing in the scheme you described.  Seeing "ar" in another thread is fine so long as it doesn't try to read beyond the available range.sent from my phoneOn Feb 22, 2015 10:53 AM, "Andy Nuss" <andrew_nuss at yahoo.com> wrote:

Hi,
I tried posting a related question on the concurrency-interest mailing list but for some reason my messages are bouncing there but not here.
Basically, the idea is that some thread has been working with an int[] and filling it with values.  From some range such as [0,8) of the array, that thread is sure never again to change those values.  Now it wishes to publish the int[] range in a threadsafe way in some new wrapper object.
It cannot construct simply this (I believe), especially if somehow another thread has seen the "ar":
class IntArray {    final int[] ar;    final int from;    final int to;    IntArray (int[] ar, int from, int to) {        this.ar = ar; this.from = from; this.to = to;
    }
}
Would it work to use this:
class IntArrayVolatile {    volatile int[] ar;    final int from;    final int to;    IntArrayVolatile (int[] ar, int from, int to) {        this.ar = ar; this.from = from; this.to = to;
    }
    IntArray publish () {        return new IntArray(ar, from, to);
    }}
and then in the thread do this:   int[] ar = new int[100];   ... fill values from [0, 8) never again to change
   IntArray publishar = new IntArrayVolatile(ar, from, to).publish();   ... give publishar to other threads   ... keep filling values from position 8 and higher in "ar" and publishing further ranges in a similar way

Obviously, this is alot about the internal workings of hotspot with the membars for volatile variables.
Andy



    


   
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20150222/4e6b6932/attachment.html>


More information about the hotspot-compiler-dev mailing list