Home | History | Annotate | Download | only in atomic
      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 sun.misc.Unsafe U = sun.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 }
    339