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

Print this page




  81         else
  82             return new LockedUpdater<U>(tclass, fieldName);
  83     }
  84 
  85     /**
  86      * Protected do-nothing constructor for use by subclasses.
  87      */
  88     protected AtomicLongFieldUpdater() {
  89     }
  90 
  91     /**
  92      * Atomically sets the field of the given object managed by this updater
  93      * to the given updated value if the current value {@code ==} the
  94      * expected value. This method is guaranteed to be atomic with respect to
  95      * other calls to {@code compareAndSet} and {@code set}, but not
  96      * necessarily with respect to other changes in the field.
  97      *
  98      * @param obj An object whose field to conditionally set
  99      * @param expect the expected value
 100      * @param update the new value
 101      * @return true if successful.
 102      * @throws ClassCastException if {@code obj} is not an instance
 103      * of the class possessing the field established in the constructor.
 104      */
 105     public abstract boolean compareAndSet(T obj, long expect, long update);
 106 
 107     /**
 108      * Atomically sets the field of the given object managed by this updater
 109      * to the given updated value if the current value {@code ==} the
 110      * expected value. This method is guaranteed to be atomic with respect to
 111      * other calls to {@code compareAndSet} and {@code set}, but not
 112      * necessarily with respect to other changes in the field.
 113      *
 114      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
 115      * and does not provide ordering guarantees, so is only rarely an
 116      * appropriate alternative to {@code compareAndSet}.
 117      *
 118      * @param obj An object whose field to conditionally set
 119      * @param expect the expected value
 120      * @param update the new value
 121      * @return true if successful.
 122      * @throws ClassCastException if {@code obj} is not an instance
 123      * of the class possessing the field established in the constructor.
 124      */
 125     public abstract boolean weakCompareAndSet(T obj, long expect, long update);
 126 
 127     /**
 128      * Sets the field of the given object managed by this updater to the
 129      * given updated value. This operation is guaranteed to act as a volatile
 130      * store with respect to subsequent invocations of {@code compareAndSet}.
 131      *
 132      * @param obj An object whose field to set
 133      * @param newValue the new value
 134      */
 135     public abstract void set(T obj, long newValue);
 136 
 137     /**
 138      * Eventually sets the field of the given object managed by this
 139      * updater to the given updated value.
 140      *
 141      * @param obj An object whose field to set


 145     public abstract void lazySet(T obj, long newValue);
 146 
 147     /**
 148      * Gets the current value held in the field of the given object managed
 149      * by this updater.
 150      *
 151      * @param obj An object whose field to get
 152      * @return the current value
 153      */
 154     public abstract long get(T obj);
 155 
 156     /**
 157      * Atomically sets the field of the given object managed by this updater
 158      * to the given value and returns the old value.
 159      *
 160      * @param obj An object whose field to get and set
 161      * @param newValue the new value
 162      * @return the previous value
 163      */
 164     public long getAndSet(T obj, long newValue) {
 165         for (;;) {
 166             long current = get(obj);
 167             if (compareAndSet(obj, current, newValue))
 168                 return current;

 169         }
 170     }
 171 
 172     /**
 173      * Atomically increments by one the current value of the field of the
 174      * given object managed by this updater.
 175      *
 176      * @param obj An object whose field to get and set
 177      * @return the previous value
 178      */
 179     public long getAndIncrement(T obj) {
 180         for (;;) {
 181             long current = get(obj);
 182             long next = current + 1;
 183             if (compareAndSet(obj, current, next))
 184                 return current;

 185         }
 186     }
 187 
 188     /**
 189      * Atomically decrements by one the current value of the field of the
 190      * given object managed by this updater.
 191      *
 192      * @param obj An object whose field to get and set
 193      * @return the previous value
 194      */
 195     public long getAndDecrement(T obj) {
 196         for (;;) {
 197             long current = get(obj);
 198             long next = current - 1;
 199             if (compareAndSet(obj, current, next))
 200                 return current;

 201         }
 202     }
 203 
 204     /**
 205      * Atomically adds the given value to the current value of the field of
 206      * the given object managed by this updater.
 207      *
 208      * @param obj An object whose field to get and set
 209      * @param delta the value to add
 210      * @return the previous value
 211      */
 212     public long getAndAdd(T obj, long delta) {
 213         for (;;) {
 214             long current = get(obj);
 215             long next = current + delta;
 216             if (compareAndSet(obj, current, next))
 217                 return current;

 218         }
 219     }
 220 
 221     /**
 222      * Atomically increments by one the current value of the field of the
 223      * given object managed by this updater.
 224      *
 225      * @param obj An object whose field to get and set
 226      * @return the updated value
 227      */
 228     public long incrementAndGet(T obj) {
 229         for (;;) {
 230             long current = get(obj);
 231             long next = current + 1;
 232             if (compareAndSet(obj, current, next))

 233                 return next;
 234         }
 235     }
 236 
 237     /**
 238      * Atomically decrements by one the current value of the field of the
 239      * given object managed by this updater.
 240      *
 241      * @param obj An object whose field to get and set
 242      * @return the updated value
 243      */
 244     public long decrementAndGet(T obj) {
 245         for (;;) {
 246             long current = get(obj);
 247             long next = current - 1;
 248             if (compareAndSet(obj, current, next))

 249                 return next;
 250         }
 251     }
 252 
 253     /**
 254      * Atomically adds the given value to the current value of the field of
 255      * the given object managed by this updater.
 256      *
 257      * @param obj An object whose field to get and set
 258      * @param delta the value to add
 259      * @return the updated value
 260      */
 261     public long addAndGet(T obj, long delta) {
 262         for (;;) {
 263             long current = get(obj);
 264             long next = current + delta;
 265             if (compareAndSet(obj, current, next))

 266                 return next;
 267         }
 268     }
 269 
 270     private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
 271         private static final Unsafe unsafe = Unsafe.getUnsafe();
 272         private final long offset;
 273         private final Class<T> tclass;
 274         private final Class<?> cclass;
 275 
 276         CASUpdater(final Class<T> tclass, final String fieldName) {
 277             final Field field;
 278             final Class<?> caller;
 279             final int modifiers;
 280             try {
 281                 field = AccessController.doPrivileged(
 282                     new PrivilegedExceptionAction<Field>() {
 283                         public Field run() throws NoSuchFieldException {
 284                             return tclass.getDeclaredField(fieldName);
 285                         }
 286                     });
 287                 caller = sun.reflect.Reflection.getCallerClass(3);
 288                 modifiers = field.getModifiers();


 328         public boolean weakCompareAndSet(T obj, long expect, long update) {
 329             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 330             return unsafe.compareAndSwapLong(obj, offset, expect, update);
 331         }
 332 
 333         public void set(T obj, long newValue) {
 334             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 335             unsafe.putLongVolatile(obj, offset, newValue);
 336         }
 337 
 338         public void lazySet(T obj, long newValue) {
 339             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 340             unsafe.putOrderedLong(obj, offset, newValue);
 341         }
 342 
 343         public long get(T obj) {
 344             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 345             return unsafe.getLongVolatile(obj, offset);
 346         }
 347 






























 348         private void ensureProtectedAccess(T obj) {
 349             if (cclass.isInstance(obj)) {
 350                 return;
 351             }
 352             throw new RuntimeException(
 353                 new IllegalAccessException("Class " +
 354                     cclass.getName() +
 355                     " can not access a protected member of class " +
 356                     tclass.getName() +
 357                     " using an instance of " +
 358                     obj.getClass().getName()
 359                 )
 360             );
 361         }
 362     }
 363 
 364 
 365     private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
 366         private static final Unsafe unsafe = Unsafe.getUnsafe();
 367         private final long offset;




  81         else
  82             return new LockedUpdater<U>(tclass, fieldName);
  83     }
  84 
  85     /**
  86      * Protected do-nothing constructor for use by subclasses.
  87      */
  88     protected AtomicLongFieldUpdater() {
  89     }
  90 
  91     /**
  92      * Atomically sets the field of the given object managed by this updater
  93      * to the given updated value if the current value {@code ==} the
  94      * expected value. This method is guaranteed to be atomic with respect to
  95      * other calls to {@code compareAndSet} and {@code set}, but not
  96      * necessarily with respect to other changes in the field.
  97      *
  98      * @param obj An object whose field to conditionally set
  99      * @param expect the expected value
 100      * @param update the new value
 101      * @return true if successful
 102      * @throws ClassCastException if {@code obj} is not an instance
 103      * of the class possessing the field established in the constructor.
 104      */
 105     public abstract boolean compareAndSet(T obj, long expect, long update);
 106 
 107     /**
 108      * Atomically sets the field of the given object managed by this updater
 109      * to the given updated value if the current value {@code ==} the
 110      * expected value. This method is guaranteed to be atomic with respect to
 111      * other calls to {@code compareAndSet} and {@code set}, but not
 112      * necessarily with respect to other changes in the field.
 113      *
 114      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
 115      * and does not provide ordering guarantees, so is only rarely an
 116      * appropriate alternative to {@code compareAndSet}.
 117      *
 118      * @param obj An object whose field to conditionally set
 119      * @param expect the expected value
 120      * @param update the new value
 121      * @return true if successful
 122      * @throws ClassCastException if {@code obj} is not an instance
 123      * of the class possessing the field established in the constructor.
 124      */
 125     public abstract boolean weakCompareAndSet(T obj, long expect, long update);
 126 
 127     /**
 128      * Sets the field of the given object managed by this updater to the
 129      * given updated value. This operation is guaranteed to act as a volatile
 130      * store with respect to subsequent invocations of {@code compareAndSet}.
 131      *
 132      * @param obj An object whose field to set
 133      * @param newValue the new value
 134      */
 135     public abstract void set(T obj, long newValue);
 136 
 137     /**
 138      * Eventually sets the field of the given object managed by this
 139      * updater to the given updated value.
 140      *
 141      * @param obj An object whose field to set


 145     public abstract void lazySet(T obj, long newValue);
 146 
 147     /**
 148      * Gets the current value held in the field of the given object managed
 149      * by this updater.
 150      *
 151      * @param obj An object whose field to get
 152      * @return the current value
 153      */
 154     public abstract long get(T obj);
 155 
 156     /**
 157      * Atomically sets the field of the given object managed by this updater
 158      * to the given value and returns the old value.
 159      *
 160      * @param obj An object whose field to get and set
 161      * @param newValue the new value
 162      * @return the previous value
 163      */
 164     public long getAndSet(T obj, long newValue) {
 165         long prev;
 166         do {
 167             prev = get(obj);
 168         } while (!compareAndSet(obj, prev, newValue));
 169         return prev;
 170     }

 171 
 172     /**
 173      * Atomically increments by one the current value of the field of the
 174      * given object managed by this updater.
 175      *
 176      * @param obj An object whose field to get and set
 177      * @return the previous value
 178      */
 179     public long getAndIncrement(T obj) {
 180         long prev, next;
 181         do {
 182             prev = get(obj);
 183             next = prev + 1;
 184         } while (!compareAndSet(obj, prev, next));
 185         return prev;
 186     }

 187 
 188     /**
 189      * Atomically decrements by one the current value of the field of the
 190      * given object managed by this updater.
 191      *
 192      * @param obj An object whose field to get and set
 193      * @return the previous value
 194      */
 195     public long getAndDecrement(T obj) {
 196         long prev, next;
 197         do {
 198             prev = get(obj);
 199             next = prev - 1;
 200         } while (!compareAndSet(obj, prev, next));
 201         return prev;
 202     }

 203 
 204     /**
 205      * Atomically adds the given value to the current value of the field of
 206      * the given object managed by this updater.
 207      *
 208      * @param obj An object whose field to get and set
 209      * @param delta the value to add
 210      * @return the previous value
 211      */
 212     public long getAndAdd(T obj, long delta) {
 213         long prev, next;
 214         do {
 215             prev = get(obj);
 216             next = prev + delta;
 217         } while (!compareAndSet(obj, prev, next));
 218         return prev;
 219     }

 220 
 221     /**
 222      * Atomically increments by one the current value of the field of the
 223      * given object managed by this updater.
 224      *
 225      * @param obj An object whose field to get and set
 226      * @return the updated value
 227      */
 228     public long incrementAndGet(T obj) {
 229         long prev, next;
 230         do {
 231             prev = get(obj);
 232             next = prev + 1;
 233         } while (!compareAndSet(obj, prev, next));
 234         return next;
 235     }

 236 
 237     /**
 238      * Atomically decrements by one the current value of the field of the
 239      * given object managed by this updater.
 240      *
 241      * @param obj An object whose field to get and set
 242      * @return the updated value
 243      */
 244     public long decrementAndGet(T obj) {
 245         long prev, next;
 246         do {
 247             prev = get(obj);
 248             next = prev - 1;
 249         } while (!compareAndSet(obj, prev, next));
 250         return next;
 251     }

 252 
 253     /**
 254      * Atomically adds the given value to the current value of the field of
 255      * the given object managed by this updater.
 256      *
 257      * @param obj An object whose field to get and set
 258      * @param delta the value to add
 259      * @return the updated value
 260      */
 261     public long addAndGet(T obj, long delta) {
 262         long prev, next;
 263         do {
 264             prev = get(obj);
 265             next = prev + delta;
 266         } while (!compareAndSet(obj, prev, next));
 267         return next;
 268     }

 269 
 270     private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
 271         private static final Unsafe unsafe = Unsafe.getUnsafe();
 272         private final long offset;
 273         private final Class<T> tclass;
 274         private final Class<?> cclass;
 275 
 276         CASUpdater(final Class<T> tclass, final String fieldName) {
 277             final Field field;
 278             final Class<?> caller;
 279             final int modifiers;
 280             try {
 281                 field = AccessController.doPrivileged(
 282                     new PrivilegedExceptionAction<Field>() {
 283                         public Field run() throws NoSuchFieldException {
 284                             return tclass.getDeclaredField(fieldName);
 285                         }
 286                     });
 287                 caller = sun.reflect.Reflection.getCallerClass(3);
 288                 modifiers = field.getModifiers();


 328         public boolean weakCompareAndSet(T obj, long expect, long update) {
 329             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 330             return unsafe.compareAndSwapLong(obj, offset, expect, update);
 331         }
 332 
 333         public void set(T obj, long newValue) {
 334             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 335             unsafe.putLongVolatile(obj, offset, newValue);
 336         }
 337 
 338         public void lazySet(T obj, long newValue) {
 339             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 340             unsafe.putOrderedLong(obj, offset, newValue);
 341         }
 342 
 343         public long get(T obj) {
 344             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 345             return unsafe.getLongVolatile(obj, offset);
 346         }
 347 
 348         public long getAndSet(T obj, long newValue) {
 349             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 350             return unsafe.getAndSetLong(obj, offset, newValue);
 351         }
 352 
 353         public long getAndIncrement(T obj) {
 354             return getAndAdd(obj, 1);
 355         }
 356 
 357         public long getAndDecrement(T obj) {
 358             return getAndAdd(obj, -1);
 359         }
 360 
 361         public long getAndAdd(T obj, long delta) {
 362             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
 363             return unsafe.getAndAddLong(obj, offset, delta);
 364         }
 365 
 366         public long incrementAndGet(T obj) {
 367             return getAndAdd(obj, 1) + 1;
 368         }
 369 
 370         public long decrementAndGet(T obj) {
 371              return getAndAdd(obj, -1) - 1;
 372         }
 373 
 374         public long addAndGet(T obj, long delta) {
 375             return getAndAdd(obj, delta) + delta;
 376         }
 377 
 378         private void ensureProtectedAccess(T obj) {
 379             if (cclass.isInstance(obj)) {
 380                 return;
 381             }
 382             throw new RuntimeException(
 383                 new IllegalAccessException("Class " +
 384                     cclass.getName() +
 385                     " can not access a protected member of class " +
 386                     tclass.getName() +
 387                     " using an instance of " +
 388                     obj.getClass().getName()
 389                 )
 390             );
 391         }
 392     }
 393 
 394 
 395     private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
 396         private static final Unsafe unsafe = Unsafe.getUnsafe();
 397         private final long offset;