JDK-8153715 : Use Unsafe.weakCompareAndSet in java.util.concurrent
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-04-07
  • Updated: 2016-07-29
  • Resolved: 2016-07-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b129Fixed
Related Reports
Relates :  
Description
With VarHandles integrated into JDK 9, we now have the opportunity to use the actual Unsafe.weakCompareAndSet entry points in java.util.concurrent, not delegate them to stronger forms.

E.g.:

diff -r 195c39d24602 src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java
--- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Thu Apr 07 15:09:03 2016 +0800
+++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Thu Apr 07 11:10:51 2016 +0300
@@ -115,9 +115,9 @@
      * @return {@code true} if successful
      */
     public boolean weakCompareAndSet(boolean expect, boolean update) {
-        return U.compareAndSwapInt(this, VALUE,
-                                   (expect ? 1 : 0),
-                                   (update ? 1 : 0));
+        return U.weakCompareAndSwapInt(this, VALUE,
+                                       (expect ? 1 : 0),
+                                       (update ? 1 : 0));
     }

Comments
A possible example of a weak cas loop: public final long getAndUpdate(LongUnaryOperator updateFunction) { long prev = get(); long next = updateFunction.applyAsLong(prev); while (!VALUE.weakCompareAndSetVolatile(this, prev, next)) { if (prev != (prev = get())) next = updateFunction.applyAsLong(prev); } return prev; }
16-06-2016

I agree that many cas loops should use the spurious-failure but sequentially consistent version of CAS for LL/SC platforms. The word "weak" is confusing because it can refer to both spurious failure AND relaxed memory model. jdk.internal.Unsafe methods are still inadequately documented, e.g. @HotSpotIntrinsicCandidate public final boolean weakCompareAndSwapObject(Object o, long offset, I think you should always get sequential consistency unless you specifically request otherwise, so the "weak" in weakCompareAndSwapObject should refer only to LL/SC style spurious failure.
18-05-2016

Note to self: this should also include rewriting CAS loops with weak*Volatile (instead of stronger) versions to cater for LL/SC platforms. Rationale: http://mail.openjdk.java.net/pipermail/jmm-dev/2016-April/000239.html
18-05-2016

jsr166 CVS has now migrated to jdk.internal.misc.Unsafe but there will be another migration to VarHandles with the goal of no longer using Unsafe at all. We should think about "weak" at that time.
25-04-2016

I should add we've been waiting for real support for weak cas for a very long time - thanks!
07-04-2016

jsr166 CVS is still using sun.misc.Unsafe instead of jdk.internal.misc.Unsafe. That will have to change before we can use any new functionality there. I'd like for Varhandles/Unsafe to settle a little in openjdk before we switch. I looked at the new weakCompareAndSwap methods in jdk.internal.misc.Unsafe. I think these methods need some documentation. As always, I am looking for a comparison "Corresponds to C11 ..." I looked at http://en.cppreference.com/w/c/atomic/atomic_compare_exchange, and C11 has two memory orders, for success and failure, a subtlety that we don't address?
07-04-2016

Full patch, derived from VarHandles forest: http://cr.openjdk.java.net/~shade/8153715/juc-weakCAS-1.patch
07-04-2016