Difference between AtomicReference.getPlain() and getOpaque()

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

Difference between AtomicReference.getPlain() and getOpaque()

Florian Weimer
Are these methods essentially the same?  I think so, based on JLS §17.7:

| Writes to and reads of references are always atomic, regardless of
| whether they are implemented as 32-bit or 64-bit values.

I assume there is a difference between getPlain() and getOpaque() for
AtomicLong because of potentially non-atomic access: I assume
getOpaque() rules that out (but that is not very clear), but
getPlain() obviously does not.

Whatabout AtomicInteger and AtomicBoolean?  Do these methods show a
difference there?
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Difference between AtomicReference.getPlain() and getOpaque()

Andrew Haley
On 15/10/17 09:38, Florian Weimer wrote:
> Are these methods essentially the same?  I think so, based on JLS §17.7:
>
> | Writes to and reads of references are always atomic, regardless of
> | whether they are implemented as 32-bit or 64-bit values.
>
> I assume there is a difference between getPlain() and getOpaque() for
> AtomicLong because of potentially non-atomic access: I assume
> getOpaque() rules that out (but that is not very clear), but
> getPlain() obviously does not.

Consider a reference field x, and a loop:

while (x == null) { }

and another thread

x = new Object();

If x is not volatile, Java compiler can hoist the load of x out of a loop
and turn that loop into

for (;;) { }

... so it loops forever.

However, it cannot do the same with getOpaque().  Eventually the read of
x will return non-null, although it may be delayed for a long time and it
won't be ordered with any other accesses.

--
Andrew Haley
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Difference between AtomicReference.getPlain() and getOpaque()

Никита Маршалкин
In reply to this post by Florian Weimer
Here's note by Doug Lea on memory orderings in JDK 9. 


On Sun, Oct 15, 2017 at 11:38 AM, Florian Weimer <[hidden email]> wrote:
Are these methods essentially the same?  I think so, based on JLS §17.7:

| Writes to and reads of references are always atomic, regardless of
| whether they are implemented as 32-bit or 64-bit values.

I assume there is a difference between getPlain() and getOpaque() for
AtomicLong because of potentially non-atomic access: I assume
getOpaque() rules that out (but that is not very clear), but
getPlain() obviously does not.

Whatabout AtomicInteger and AtomicBoolean?  Do these methods show a
difference there?
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



--
Yours sincerely,
Nikita Marshalkin.

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

Re: Difference between AtomicReference.getPlain() and getOpaque()

Aleksey Shipilev-3
On 10/15/2017 10:54 AM, Никита Маршалкин wrote:
> Here's note by Doug Lea on memory orderings in JDK 9. 
>
> http://gee.cs.oswego.edu/dl/html/j9mm.html <http://gee.cs.oswego.edu/dl/html/j9mm.html>

TL;DR: "opaque" = "plain" + access atomicity + coherence + eventual progress

Access atomicity:
 http://hg.openjdk.java.net/code-tools/jcstress/file/6a9ce3b8ccc4/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JMMSample_01_AccessAtomicity.java

Coherence:
 http://hg.openjdk.java.net/code-tools/jcstress/file/6a9ce3b8ccc4/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JMMSample_03_Coherence.java

Thanks,
-Aleksey


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

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Difference between AtomicReference.getPlain() and getOpaque()

Florian Weimer
In reply to this post by Andrew Haley
* Andrew Haley:

> On 15/10/17 09:38, Florian Weimer wrote:
>> Are these methods essentially the same?  I think so, based on JLS §17.7:
>>
>> | Writes to and reads of references are always atomic, regardless of
>> | whether they are implemented as 32-bit or 64-bit values.
>>
>> I assume there is a difference between getPlain() and getOpaque() for
>> AtomicLong because of potentially non-atomic access: I assume
>> getOpaque() rules that out (but that is not very clear), but
>> getPlain() obviously does not.
>
> Consider a reference field x, and a loop:
>
> while (x == null) { }
>
> and another thread
>
> x = new Object();
>
> If x is not volatile, Java compiler can hoist the load of x out of a loop
> and turn that loop into
>
> for (;;) { }
>
> ... so it loops forever.
>
> However, it cannot do the same with getOpaque().  Eventually the read of
> x will return non-null, although it may be delayed for a long time and it
> won't be ordered with any other accesses.

Thanks, with this and (the reference Никита provided), it's clear that
they are not the same.  It's really not obvious based on JLS 9 and the
JDK 9 API documentation that there are additional constraints on the
implementation here.  The description of the memory model in the JLS
could at least say that it's not been updated for the introduction of
opaque accesses in JDK 9. 8-/
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Difference between AtomicReference.getPlain() and getOpaque()

Andrew Haley
On 15/10/17 10:23, Florian Weimer wrote:
> Thanks, with this and (the reference Никита provided), it's clear that
> they are not the same.  It's really not obvious based on JLS 9 and the
> JDK 9 API documentation that there are additional constraints on the
> implementation here.  The description of the memory model in the JLS
> could at least say that it's not been updated for the introduction of
> opaque accesses in JDK 9.

"Obvious" is perhaps not the word to use in this context.  It seems to
be extraordinarily difficult to specify extensions to the JMM (and,
indeed, the JMM itself) in a way that makes sense to most Java
programmers.  But the behaviour I described is implied by the spec:

getPlain()

     * Returns the current value, with memory semantics of reading as
     * if the variable was declared non-{@code volatile}.

getOpaque()

     * Returns the value of a variable, accessed in program order, but
     * with no assurance of memory ordering effects with respect to
     * other threads.

The key phrase here is "accessed in program order," but most
programmers won't notice its significance.

--
Andrew Haley
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest