1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  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 
  38 import java.util.function.IntBinaryOperator;
  39 import java.util.function.IntUnaryOperator;
  40 
  41 /**
  42  * An {@code int} value that may be updated atomically.  See the
  43  * {@link java.util.concurrent.atomic} package specification for
  44  * description of the properties of atomic variables. An
  45  * {@code AtomicInteger} is used in applications such as atomically
  46  * incremented counters, and cannot be used as a replacement for an
  47  * {@link java.lang.Integer}. However, this class does extend
  48  * {@code Number} to allow uniform access by tools and utilities that
  49  * deal with numerically-based classes.
  50  *
  51  * @since 1.5
  52  * @author Doug Lea
  53  */
  54 public class AtomicInteger extends Number implements java.io.Serializable {
  55     private static final long serialVersionUID = 6214790243416807050L;
  56 
  57     private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
  58     private static final long VALUE;
  59 
  60     static {
  61         try {
  62             VALUE = U.objectFieldOffset
  63                 (AtomicInteger.class.getDeclaredField("value"));
  64         } catch (ReflectiveOperationException e) {
  65             throw new Error(e);
  66         }
  67     }
  68 
  69     private volatile int value;
  70 
  71     /**
  72      * Creates a new AtomicInteger with the given initial value.
  73      *
  74      * @param initialValue the initial value
  75      */
  76     public AtomicInteger(int initialValue) {
  77         value = initialValue;
  78     }
  79 
  80     /**
  81      * Creates a new AtomicInteger with initial value {@code 0}.
  82      */
  83     public AtomicInteger() {
  84     }
  85 
  86     /**
  87      * Gets the current value.
  88      *
  89      * @return the current value
  90      */
  91     public final int get() {
  92         return value;
  93     }
  94 
  95     /**
  96      * Sets to the given value.
  97      *
  98      * @param newValue the new value
  99      */
 100     public final void set(int newValue) {
 101         value = newValue;
 102     }
 103 
 104     /**
 105      * Eventually sets to the given value.
 106      *
 107      * @param newValue the new value
 108      * @since 1.6
 109      */
 110     public final void lazySet(int newValue) {
 111         U.putOrderedInt(this, VALUE, newValue);
 112     }
 113 
 114     /**
 115      * Atomically sets to the given value and returns the old value.
 116      *
 117      * @param newValue the new value
 118      * @return the previous value
 119      */
 120     public final int getAndSet(int newValue) {
 121         return U.getAndSetInt(this, VALUE, newValue);
 122     }
 123 
 124     /**
 125      * Atomically sets the value to the given updated value
 126      * if the current value {@code ==} the expected value.
 127      *
 128      * @param expect the expected value
 129      * @param update the new value
 130      * @return {@code true} if successful. False return indicates that
 131      * the actual value was not equal to the expected value.
 132      */
 133     public final boolean compareAndSet(int expect, int update) {
 134         return U.compareAndSwapInt(this, VALUE, expect, update);
 135     }
 136 
 137     /**
 138      * Atomically sets the value to the given updated value
 139      * if the current value {@code ==} the expected value.
 140      *
 141      * <p><a href="package-summary.html#weakCompareAndSet">May fail
 142      * spuriously and does not provide ordering guarantees</a>, so is
 143      * only rarely an appropriate alternative to {@code compareAndSet}.
 144      *
 145      * @param expect the expected value
 146      * @param update the new value
 147      * @return {@code true} if successful
 148      */
 149     public final boolean weakCompareAndSet(int expect, int update) {
 150         return U.compareAndSwapInt(this, VALUE, expect, update);
 151     }
 152 
 153     /**
 154      * Atomically increments by one the current value.
 155      *
 156      * @return the previous value
 157      */
 158     public final int getAndIncrement() {
 159         return U.getAndAddInt(this, VALUE, 1);
 160     }
 161 
 162     /**
 163      * Atomically decrements by one the current value.
 164      *
 165      * @return the previous value
 166      */
 167     public final int getAndDecrement() {
 168         return U.getAndAddInt(this, VALUE, -1);
 169     }
 170 
 171     /**
 172      * Atomically adds the given value to the current value.
 173      *
 174      * @param delta the value to add
 175      * @return the previous value
 176      */
 177     public final int getAndAdd(int delta) {
 178         return U.getAndAddInt(this, VALUE, delta);
 179     }
 180 
 181     /**
 182      * Atomically increments by one the current value.
 183      *
 184      * @return the updated value
 185      */
 186     public final int incrementAndGet() {
 187         return U.getAndAddInt(this, VALUE, 1) + 1;
 188     }
 189 
 190     /**
 191      * Atomically decrements by one the current value.
 192      *
 193      * @return the updated value
 194      */
 195     public final int decrementAndGet() {
 196         return U.getAndAddInt(this, VALUE, -1) - 1;
 197     }
 198 
 199     /**
 200      * Atomically adds the given value to the current value.
 201      *
 202      * @param delta the value to add
 203      * @return the updated value
 204      */
 205     public final int addAndGet(int delta) {
 206         return U.getAndAddInt(this, VALUE, delta) + delta;
 207     }
 208 
 209     /**
 210      * Atomically updates the current value with the results of
 211      * applying the given function, returning the previous value. The
 212      * function should be side-effect-free, since it may be re-applied
 213      * when attempted updates fail due to contention among threads.
 214      *
 215      * @param updateFunction a side-effect-free function
 216      * @return the previous value
 217      * @since 1.8
 218      */
 219     public final int getAndUpdate(IntUnaryOperator updateFunction) {
 220         int prev, next;
 221         do {
 222             prev = get();
 223             next = updateFunction.applyAsInt(prev);
 224         } while (!compareAndSet(prev, next));
 225         return prev;
 226     }
 227 
 228     /**
 229      * Atomically updates the current value with the results of
 230      * applying the given function, returning the updated value. The
 231      * function should be side-effect-free, since it may be re-applied
 232      * when attempted updates fail due to contention among threads.
 233      *
 234      * @param updateFunction a side-effect-free function
 235      * @return the updated value
 236      * @since 1.8
 237      */
 238     public final int updateAndGet(IntUnaryOperator updateFunction) {
 239         int prev, next;
 240         do {
 241             prev = get();
 242             next = updateFunction.applyAsInt(prev);
 243         } while (!compareAndSet(prev, next));
 244         return next;
 245     }
 246 
 247     /**
 248      * Atomically updates the current value with the results of
 249      * applying the given function to the current and given values,
 250      * returning the previous value. The function should be
 251      * side-effect-free, since it may be re-applied when attempted
 252      * updates fail due to contention among threads.  The function
 253      * is applied with the current value as its first argument,
 254      * and the given update as the second argument.
 255      *
 256      * @param x the update value
 257      * @param accumulatorFunction a side-effect-free function of two arguments
 258      * @return the previous value
 259      * @since 1.8
 260      */
 261     public final int getAndAccumulate(int x,
 262                                       IntBinaryOperator accumulatorFunction) {
 263         int prev, next;
 264         do {
 265             prev = get();
 266             next = accumulatorFunction.applyAsInt(prev, x);
 267         } while (!compareAndSet(prev, next));
 268         return prev;
 269     }
 270 
 271     /**
 272      * Atomically updates the current value with the results of
 273      * applying the given function to the current and given values,
 274      * returning the updated value. The function should be
 275      * side-effect-free, since it may be re-applied when attempted
 276      * updates fail due to contention among threads.  The function
 277      * is applied with the current value as its first argument,
 278      * and the given update as the second argument.
 279      *
 280      * @param x the update value
 281      * @param accumulatorFunction a side-effect-free function of two arguments
 282      * @return the updated value
 283      * @since 1.8
 284      */
 285     public final int accumulateAndGet(int x,
 286                                       IntBinaryOperator accumulatorFunction) {
 287         int prev, next;
 288         do {
 289             prev = get();
 290             next = accumulatorFunction.applyAsInt(prev, x);
 291         } while (!compareAndSet(prev, next));
 292         return next;
 293     }
 294 
 295     /**
 296      * Returns the String representation of the current value.
 297      * @return the String representation of the current value
 298      */
 299     public String toString() {
 300         return Integer.toString(get());
 301     }
 302 
 303     /**
 304      * Returns the value of this {@code AtomicInteger} as an {@code int}.
 305      * Equivalent to {@link #get()}.
 306      */
 307     public int intValue() {
 308         return get();
 309     }
 310 
 311     /**
 312      * Returns the value of this {@code AtomicInteger} as a {@code long}
 313      * after a widening primitive conversion.
 314      * @jls 5.1.2 Widening Primitive Conversions
 315      */
 316     public long longValue() {
 317         return (long)get();
 318     }
 319 
 320     /**
 321      * Returns the value of this {@code AtomicInteger} as a {@code float}
 322      * after a widening primitive conversion.
 323      * @jls 5.1.2 Widening Primitive Conversions
 324      */
 325     public float floatValue() {
 326         return (float)get();
 327     }
 328 
 329     /**
 330      * Returns the value of this {@code AtomicInteger} as a {@code double}
 331      * after a widening primitive conversion.
 332      * @jls 5.1.2 Widening Primitive Conversions
 333      */
 334     public double doubleValue() {
 335         return (double)get();
 336     }
 337 
 338 }