src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java

Print this page

        

@@ -114,11 +114,11 @@
      * necessarily with respect to other changes in the field.
      *
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public abstract boolean compareAndSet(T obj, V expect, V update);
 
     /**
      * Atomically sets the field of the given object managed by this updater

@@ -132,11 +132,11 @@
      * appropriate alternative to {@code compareAndSet}.
      *
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public abstract boolean weakCompareAndSet(T obj, V expect, V update);
 
     /**
      * Sets the field of the given object managed by this updater to the

@@ -174,16 +174,16 @@
      * @param obj An object whose field to get and set
      * @param newValue the new value
      * @return the previous value
      */
     public V getAndSet(T obj, V newValue) {
-        for (;;) {
-            V current = get(obj);
-            if (compareAndSet(obj, current, newValue))
-                return current;
+        V prev;
+        do {
+            prev = get(obj);
+        } while (!compareAndSet(obj, prev, newValue));
+        return prev;
         }
-    }
 
     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
         extends AtomicReferenceFieldUpdater<T,V> {
         private static final Unsafe unsafe = Unsafe.getUnsafe();
         private final long offset;

@@ -319,10 +319,19 @@
             if (obj == null || obj.getClass() != tclass || cclass != null)
                 targetCheck(obj);
             return (V)unsafe.getObjectVolatile(obj, offset);
         }
 
+        @SuppressWarnings("unchecked")
+        public V getAndSet(T obj, V newValue) {
+            if (obj == null || obj.getClass() != tclass || cclass != null ||
+                (newValue != null && vclass != null &&
+                 vclass != newValue.getClass()))
+                updateCheck(obj, newValue);
+            return (V)unsafe.getAndSetObject(obj, offset, newValue);
+        }
+
         private void ensureProtectedAccess(T obj) {
             if (cclass.isInstance(obj)) {
                 return;
             }
             throw new RuntimeException(