Fwd: easiest way to force a write membar in jdk7 and 8

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Fwd: easiest way to force a write membar in jdk7 and 8

Doug Lea

Forwarding for Andy..

-------- Forwarded Message --------
Subject: easiest way to force a write membar in jdk7 and 8
Date: Sun, 22 Feb 2015 15:52:41 +0000 (UTC)
From: Andy Nuss <[hidden email]>
Reply-To: Andy Nuss <[hidden email]>
To: Hotspot Compiler <[hidden email]>



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


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: easiest way to force a write membar in jdk7 and 8

oleksandr otenko
Can someone explain what becomes a problem when some other thread "sees
the ar", when clone is created with finals?

Alex

On 22/02/2015 16:05, Doug Lea wrote:

>
> Forwarding for Andy..
>
> -------- Forwarded Message --------
> Subject:     easiest way to force a write membar in jdk7 and 8
> Date:     Sun, 22 Feb 2015 15:52:41 +0000 (UTC)
> From:     Andy Nuss <[hidden email]>
> Reply-To:     Andy Nuss <[hidden email]>
> To:     Hotspot Compiler <[hidden email]>
>
>
>
> 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
>
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: easiest way to force a write membar in jdk7 and 8

Vladimir Sitnikov
> Now it wishes to publish the int[] range in a thread-safe way in some new wrapper object.

JMM does not work like that. You can't create multiple "thread-safe wrappers" that are safe for use across data races.
Here's theoretical minimum:
1) volatile field does not result in a "safe publishing wrapper". For instance, you could get 0 if publish new AtomicInteger(42) via data race.
2) "final wrappers" do not work if you publish the base object (not the wrapper) multiple times.
You do not have a second chance to publish an "a bit updated object" via "final wrapper".

> give publishar to other threads

Can you clarify if any of your consumer threads need to have at least two views of the same base "ar"?
In other words: do you always publish object to a fresh thread?

If a thread needs to consume "ar" at least twice, you'd better have some reasonable happens-before edge.

Vladimir

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: easiest way to force a write membar in jdk7 and 8

tm jee
This should work, can someone confirm this.

class IntArray {
 
   final int[] iiAr;
   final int from, to;
   IntArrayVolatile(int[] iAr, int from, int to) {
       int[] temp = iAr;
       iiAr = System.arraycopy(....); // copy from temp to iiAr
        this.from = from; 
       this.to=to;
   }
}

class IntArrayVolatile {

   volatile int[] w = ....
   
   // the same only one thread execute this
   public IntArray[] publish(...) {
       int[] _w = w;
       return new IntArrayVolatile(._w...);
   }

   // the same and only one thread execute this
   public void modify(....) {
       int[] _w = System.arraycopy(....); // copy of w
       // modify _w
       w = _w;
   }
}





On Tue, Feb 24, 2015 at 8:22 AM, Vladimir Sitnikov <[hidden email]> wrote:
> Now it wishes to publish the int[] range in a thread-safe way in some new wrapper object.

JMM does not work like that. You can't create multiple "thread-safe wrappers" that are safe for use across data races.
Here's theoretical minimum:
1) volatile field does not result in a "safe publishing wrapper". For instance, you could get 0 if publish new AtomicInteger(42) via data race.
2) "final wrappers" do not work if you publish the base object (not the wrapper) multiple times.
You do not have a second chance to publish an "a bit updated object" via "final wrapper".

> give publishar to other threads

Can you clarify if any of your consumer threads need to have at least two views of the same base "ar"?
In other words: do you always publish object to a fresh thread?

If a thread needs to consume "ar" at least twice, you'd better have some reasonable happens-before edge.

Vladimir

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: easiest way to force a write membar in jdk7 and 8

Andrew Haley
On 27/02/15 06:53, tm jee wrote:
> This should work, can someone confirm this.

It's hard to understand exactly what your example is supposed
to do, but I see no happens-before edge between the writer
and the reader.

Andrew.

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest