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

Print this page




  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * This file is available under and governed by the GNU General Public
  27  * License version 2 only, as published by the Free Software Foundation.
  28  * However, the following notice accompanied the original version of this
  29  * file:
  30  *
  31  * Written by Doug Lea with assistance from members of JCP JSR-166
  32  * Expert Group and released to the public domain, as explained at
  33  * http://creativecommons.org/publicdomain/zero/1.0/
  34  */
  35 
  36 package java.util.concurrent.atomic;


  37 import sun.misc.Unsafe;
  38 import java.lang.reflect.Field;
  39 import java.lang.reflect.Modifier;
  40 import java.security.AccessController;
  41 import java.security.PrivilegedExceptionAction;
  42 import java.security.PrivilegedActionException;
  43 
  44 /**
  45  * A reflection-based utility that enables atomic updates to
  46  * designated {@code volatile int} fields of designated classes.
  47  * This class is designed for use in atomic data structures in which
  48  * several fields of the same node are independently subject to atomic
  49  * updates.
  50  *
  51  * <p>Note that the guarantees of the {@code compareAndSet}
  52  * method in this class are weaker than in other atomic classes.
  53  * Because this class cannot ensure that all uses of the field
  54  * are appropriate for purposes of atomic access, it can
  55  * guarantee atomicity only with respect to other invocations of
  56  * {@code compareAndSet} and {@code set} on the same updater.


 245             next = prev - 1;
 246         } while (!compareAndSet(obj, prev, next));
 247         return next;
 248     }
 249 
 250     /**
 251      * Atomically adds the given value to the current value of the field of
 252      * the given object managed by this updater.
 253      *
 254      * @param obj An object whose field to get and set
 255      * @param delta the value to add
 256      * @return the updated value
 257      */
 258     public int addAndGet(T obj, int delta) {
 259         int prev, next;
 260         do {
 261             prev = get(obj);
 262             next = prev + delta;
 263         } while (!compareAndSet(obj, prev, next));
 264         return next;
























































































 265     }
 266 
 267     /**
 268      * Standard hotspot implementation using intrinsics
 269      */
 270     private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<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         AtomicIntegerFieldUpdaterImpl(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);




  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * This file is available under and governed by the GNU General Public
  27  * License version 2 only, as published by the Free Software Foundation.
  28  * However, the following notice accompanied the original version of this
  29  * file:
  30  *
  31  * Written by Doug Lea with assistance from members of JCP JSR-166
  32  * Expert Group and released to the public domain, as explained at
  33  * http://creativecommons.org/publicdomain/zero/1.0/
  34  */
  35 
  36 package java.util.concurrent.atomic;
  37 import java.util.function.IntUnaryOperator;
  38 import java.util.function.IntBinaryOperator;
  39 import sun.misc.Unsafe;
  40 import java.lang.reflect.Field;
  41 import java.lang.reflect.Modifier;
  42 import java.security.AccessController;
  43 import java.security.PrivilegedExceptionAction;
  44 import java.security.PrivilegedActionException;
  45 
  46 /**
  47  * A reflection-based utility that enables atomic updates to
  48  * designated {@code volatile int} fields of designated classes.
  49  * This class is designed for use in atomic data structures in which
  50  * several fields of the same node are independently subject to atomic
  51  * updates.
  52  *
  53  * <p>Note that the guarantees of the {@code compareAndSet}
  54  * method in this class are weaker than in other atomic classes.
  55  * Because this class cannot ensure that all uses of the field
  56  * are appropriate for purposes of atomic access, it can
  57  * guarantee atomicity only with respect to other invocations of
  58  * {@code compareAndSet} and {@code set} on the same updater.


 247             next = prev - 1;
 248         } while (!compareAndSet(obj, prev, next));
 249         return next;
 250     }
 251 
 252     /**
 253      * Atomically adds the given value to the current value of the field of
 254      * the given object managed by this updater.
 255      *
 256      * @param obj An object whose field to get and set
 257      * @param delta the value to add
 258      * @return the updated value
 259      */
 260     public int addAndGet(T obj, int delta) {
 261         int prev, next;
 262         do {
 263             prev = get(obj);
 264             next = prev + delta;
 265         } while (!compareAndSet(obj, prev, next));
 266         return next;
 267     }
 268 
 269     /**
 270      * Atomically updates the current value with the results of
 271      * applying the given function. The function should be
 272      * side-effect-free, since it may be re-applied when attempted
 273      * updates fail due to contention among threads.
 274      *
 275      * @param obj An object whose field to get and set
 276      * @param updateFunction a side-effect-free function
 277      * @return the previous value
 278      * @since 1.8
 279      */
 280     public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) {
 281         int prev, next;
 282         do {
 283             prev = get(obj);
 284             next = updateFunction.operateAsInt(prev);
 285         } while (!compareAndSet(obj, prev, next));
 286         return prev;
 287     }
 288 
 289     /**
 290      * Atomically updates the current value with the results of
 291      * applying the given function. The function should be
 292      * side-effect-free, since it may be re-applied when attempted
 293      * updates fail due to contention among threads.
 294      *
 295      * @param obj An object whose field to get and set
 296      * @param updateFunction a side-effect-free function
 297      * @return the updated value
 298      * @since 1.8
 299      */
 300     public final int updateAndGet(T obj, IntUnaryOperator updateFunction) {
 301         int prev, next;
 302         do {
 303             prev = get(obj);
 304             next = updateFunction.operateAsInt(prev);
 305         } while (!compareAndSet(obj, prev, next));
 306         return next;
 307     }
 308 
 309     /**
 310      * Atomically updates the current value with the results of
 311      * applying the given function to the current and given values.
 312      * The function should be side-effect-free, since it may be
 313      * re-applied when attempted updates fail due to contention among
 314      * threads.  The function is applied with the current value as its
 315      * first argument, and the given update as the second argument.
 316      *
 317      * @param obj An object whose field to get and set
 318      * @param x the update value
 319      * @param accumulatorFunction a side-effect-free function of two arguments
 320      * @return the previous value
 321      * @since 1.8
 322      */
 323     public final int getAndAccumulate(T obj, int x,
 324                                       IntBinaryOperator accumulatorFunction) {
 325         int prev, next;
 326         do {
 327             prev = get(obj);
 328             next = accumulatorFunction.operateAsInt(prev, x);
 329         } while (!compareAndSet(obj, prev, next));
 330         return prev;
 331     }
 332 
 333     /**
 334      * Atomically updates the current value with the results of
 335      * applying the given function to the current and given values.
 336      * The function should be side-effect-free, since it may be
 337      * re-applied when attempted updates fail due to contention among
 338      * threads.  The function is applied with the current value as its
 339      * first argument, and the given update as the second argument.
 340      *
 341      * @param obj An object whose field to get and set
 342      * @param x the update value
 343      * @param accumulatorFunction a side-effect-free function of two arguments
 344      * @return the updated value
 345      * @since 1.8
 346      */
 347     public final int accumulateAndGet(T obj, int x,
 348                                       IntBinaryOperator accumulatorFunction) {
 349         int prev, next;
 350         do {
 351             prev = get(obj);
 352             next = accumulatorFunction.operateAsInt(prev, x);
 353         } while (!compareAndSet(obj, prev, next));
 354         return next;
 355     }
 356 
 357     /**
 358      * Standard hotspot implementation using intrinsics
 359      */
 360     private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
 361         private static final Unsafe unsafe = Unsafe.getUnsafe();
 362         private final long offset;
 363         private final Class<T> tclass;
 364         private final Class<?> cclass;
 365 
 366         AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) {
 367             final Field field;
 368             final Class<?> caller;
 369             final int modifiers;
 370             try {
 371                 field = AccessController.doPrivileged(
 372                     new PrivilegedExceptionAction<Field>() {
 373                         public Field run() throws NoSuchFieldException {
 374                             return tclass.getDeclaredField(fieldName);