前言:

  Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便在多线程环境下进行原子操作。原子变量的底层使用了CPU提供的原子指令,但是不同的CPU架构可能提供的原子指令不一样,也有可能需要某种形式的内部锁,所以该方法不能绝对保证线程不被阻塞。

包介绍:

[多线程系列]Java 中atomic包的解析

在atomic包里一共有12个类,四种原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新字段。Atomic包里的类基本都是使用Unsafe实现的包装类。

原子更新基本类型

  • AtomicInteger
  • AtomicLong
  • AtomicBoolean

原子更新引用

  • AtomicReference
  • AtomicMarkableReference
  • AtomicStampedReference 

原子更新数组

  • AtomicIntegerArray
  • AtomicLongArray
  • AtomicReferenceArray

原子更新字段

  • AtomicIntegerFieldUpdater
  • AtomicLongFieldUpdater
  • AtomicReferenceFieldUpdater

 

以下主要分析AtomicInteger,其他类大同小异

源码:

  

  1 /*
  2  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  3  *
  4  *
  5  *
  6  *
  7  *
  8  *
  9  *
 10  *
 11  *
 12  *
 13  *
 14  *
 15  *
 16  *
 17  *
 18  *
 19  *
 20  *
 21  *
 22  *
 23  */
 24 
 25 /*
 26  *
 27  *
 28  *
 29  *
 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 
 39 /**
 40  * An {@code int} value that may be updated atomically.  See the
 41  * {@link java.util.concurrent.atomic} package specification for
 42  * description of the properties of atomic variables. An
 43  * {@code AtomicInteger} is used in applications such as atomically
 44  * incremented counters, and cannot be used as a replacement for an
 45  * {@link java.lang.Integer}. However, this class does extend
 46  * {@code Number} to allow uniform access by tools and utilities that
 47  * deal with numerically-based classes.
 48  *
 49  * @since 1.5
 50  * @author Doug Lea
 51 */
 52 public class AtomicInteger extends Number implements java.io.Serializable {
 53     private static final long serialVersionUID = 6214790243416807050L;
 54 
 55     // setup to use Unsafe.compareAndSwapInt for updates
 56     private static final Unsafe unsafe = Unsafe.getUnsafe();
 57     private static final long valueOffset;
 58 
 59     static {
 60       try {
 61         valueOffset = unsafe.objectFieldOffset
 62             (AtomicInteger.class.getDeclaredField("value"));
 63       } catch (Exception ex) { throw new Error(ex); }
 64     }
 65 
 66     private volatile int value;
 67 
 68     /**
 69      * Creates a new AtomicInteger with the given initial value.
 70      *
 71      * @param initialValue the initial value
 72      */
 73     public AtomicInteger(int initialValue) {
 74         value = initialValue;
 75     }
 76 
 77     /**
 78      * Creates a new AtomicInteger with initial value {@code 0}.
 79      */
 80     public AtomicInteger() {
 81     }
 82 
 83     /**
 84      * Gets the current value.
 85      *
 86      * @return the current value
 87      */
 88     public final int get() {
 89         return value;
 90     }
 91 
 92     /**
 93      * Sets to the given value.
 94      *
 95      * @param newValue the new value
 96      */
 97     public final void set(int newValue) {
 98         value = newValue;
 99     }
100 
101     /**
102      * Eventually sets to the given value.
103      *
104      * @param newValue the new value
105      * @since 1.6
106      */
107     public final void lazySet(int newValue) {
108         unsafe.putOrderedInt(this, valueOffset, newValue);
109     }
110 
111     /**
112      * Atomically sets to the given value and returns the old value.
113      *
114      * @param newValue the new value
115      * @return the previous value
116      */
117     public final int getAndSet(int newValue) {
118         for (;;) {
119             int current = get();
120             if (compareAndSet(current, newValue))
121                 return current;
122         }
123     }
124 
125     /**
126      * Atomically sets the value to the given updated value
127      * if the current value {@code ==} the expected value.
128      *
129      * @param expect the expected value
130      * @param update the new value
131      * @return true if successful. False return indicates that
132      * the actual value was not equal to the expected value.
133      */
134     public final boolean compareAndSet(int expect, int update) {
135         return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
136     }
137 
138     /**
139      * Atomically sets the value to the given updated value
140      * if the current value {@code ==} the expected value.
141      *
142      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
143      * and does not provide ordering guarantees, so is only rarely an
144      * appropriate alternative to {@code compareAndSet}.
145      *
146      * @param expect the expected value
147      * @param update the new value
148      * @return true if successful.
149      */
150     public final boolean weakCompareAndSet(int expect, int update) {
151         return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
152     }
153 
154     /**
155      * Atomically increments by one the current value.
156      *
157      * @return the previous value
158      */
159     public final int getAndIncrement() {
160         for (;;) {
161             int current = get();
162             int next = current + 1;
163             if (compareAndSet(current, next))
164                 return current;
165         }
166     }
167 
168     /**
169      * Atomically decrements by one the current value.
170      *
171      * @return the previous value
172      */
173     public final int getAndDecrement() {
174         for (;;) {
175             int current = get();
176             int next = current - 1;
177             if (compareAndSet(current, next))
178                 return current;
179         }
180     }
181 
182     /**
183      * Atomically adds the given value to the current value.
184      *
185      * @param delta the value to add
186      * @return the previous value
187      */
188     public final int getAndAdd(int delta) {
189         for (;;) {
190             int current = get();
191             int next = current + delta;
192             if (compareAndSet(current, next))
193                 return current;
194         }
195     }
196 
197     /**
198      * Atomically increments by one the current value.
199      *
200      * @return the updated value
201      */
202     public final int incrementAndGet() {
203         for (;;) {
204             int current = get();
205             int next = current + 1;
206             if (compareAndSet(current, next))
207                 return next;
208         }
209     }
210 
211     /**
212      * Atomically decrements by one the current value.
213      *
214      * @return the updated value
215      */
216     public final int decrementAndGet() {
217         for (;;) {
218             int current = get();
219             int next = current - 1;
220             if (compareAndSet(current, next))
221                 return next;
222         }
223     }
224 
225     /**
226      * Atomically adds the given value to the current value.
227      *
228      * @param delta the value to add
229      * @return the updated value
230      */
231     public final int addAndGet(int delta) {
232         for (;;) {
233             int current = get();
234             int next = current + delta;
235             if (compareAndSet(current, next))
236                 return next;
237         }
238     }
239 
240     /**
241      * Returns the String representation of the current value.
242      * @return the String representation of the current value.
243      */
244     public String toString() {
245         return Integer.toString(get());
246     }
247 
248 
249     public int intValue() {
250         return get();
251     }
252 
253     public long longValue() {
254         return (long)get();
255     }
256 
257     public float floatValue() {
258         return (float)get();
259     }
260 
261     public double doubleValue() {
262         return (double)get();
263     }
264 
265 }
AtomicInteger

相关文章:

  • 2021-07-24
  • 2022-01-30
  • 2021-07-10
  • 2022-02-04
  • 2021-10-31
  • 2022-02-09
  • 2022-12-23
  • 2021-11-17
猜你喜欢
  • 2021-12-12
  • 2022-03-07
  • 2021-08-02
  • 2021-11-27
  • 2021-09-28
  • 2021-07-16
相关资源
相似解决方案