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

Print this page

        

@@ -96,11 +96,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
      * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor.
      */
     public abstract boolean compareAndSet(T obj, long expect, long update);
 

@@ -116,11 +116,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
      * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor.
      */
     public abstract boolean weakCompareAndSet(T obj, long expect, long update);
 

@@ -160,48 +160,48 @@
      * @param obj An object whose field to get and set
      * @param newValue the new value
      * @return the previous value
      */
     public long getAndSet(T obj, long newValue) {
-        for (;;) {
-            long current = get(obj);
-            if (compareAndSet(obj, current, newValue))
-                return current;
+        long prev;
+        do {
+            prev = get(obj);
+        } while (!compareAndSet(obj, prev, newValue));
+        return prev;
         }
-    }
 
     /**
      * Atomically increments by one the current value of the field of the
      * given object managed by this updater.
      *
      * @param obj An object whose field to get and set
      * @return the previous value
      */
     public long getAndIncrement(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return current;
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
         }
-    }
 
     /**
      * Atomically decrements by one the current value of the field of the
      * given object managed by this updater.
      *
      * @param obj An object whose field to get and set
      * @return the previous value
      */
     public long getAndDecrement(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return current;
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
         }
-    }
 
     /**
      * Atomically adds the given value to the current value of the field of
      * the given object managed by this updater.
      *

@@ -208,49 +208,49 @@
      * @param obj An object whose field to get and set
      * @param delta the value to add
      * @return the previous value
      */
     public long getAndAdd(T obj, long delta) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return current;
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
         }
-    }
 
     /**
      * Atomically increments by one the current value of the field of the
      * given object managed by this updater.
      *
      * @param obj An object whose field to get and set
      * @return the updated value
      */
     public long incrementAndGet(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + 1;
-            if (compareAndSet(obj, current, next))
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
                 return next;
         }
-    }
 
     /**
      * Atomically decrements by one the current value of the field of the
      * given object managed by this updater.
      *
      * @param obj An object whose field to get and set
      * @return the updated value
      */
     public long decrementAndGet(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current - 1;
-            if (compareAndSet(obj, current, next))
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
                 return next;
         }
-    }
 
     /**
      * Atomically adds the given value to the current value of the field of
      * the given object managed by this updater.
      *

@@ -257,17 +257,17 @@
      * @param obj An object whose field to get and set
      * @param delta the value to add
      * @return the updated value
      */
     public long addAndGet(T obj, long delta) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + delta;
-            if (compareAndSet(obj, current, next))
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
                 return next;
         }
-    }
 
     private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
         private static final Unsafe unsafe = Unsafe.getUnsafe();
         private final long offset;
         private final Class<T> tclass;

@@ -343,10 +343,40 @@
         public long get(T obj) {
             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.getLongVolatile(obj, offset);
         }
 
+        public long getAndSet(T obj, long newValue) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+            return unsafe.getAndSetLong(obj, offset, newValue);
+        }
+
+        public long getAndIncrement(T obj) {
+            return getAndAdd(obj, 1);
+        }
+
+        public long getAndDecrement(T obj) {
+            return getAndAdd(obj, -1);
+        }
+
+        public long getAndAdd(T obj, long delta) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+            return unsafe.getAndAddLong(obj, offset, delta);
+        }
+
+        public long incrementAndGet(T obj) {
+            return getAndAdd(obj, 1) + 1;
+        }
+
+        public long decrementAndGet(T obj) {
+             return getAndAdd(obj, -1) - 1;
+        }
+
+        public long addAndGet(T obj, long delta) {
+            return getAndAdd(obj, delta) + delta;
+        }
+
         private void ensureProtectedAccess(T obj) {
             if (cclass.isInstance(obj)) {
                 return;
             }
             throw new RuntimeException(