前言
JDK1.5之后的java.util.concurrent.atomic包里,多了一批原子處理類吱七。AtomicBoolean垃杖、AtomicInteger奈辰、AtomicLong、AtomicReference。主要用于在高并發(fā)環(huán)境下的高效程序處理,來幫助我們簡化同步處理.
AtomicInteger
AtomicInteger辜窑,一個提供原子操作的Integer的類钩述。在Java語言中,++i和i++操作并不是線程安全的穆碎,在使用的時候牙勘,不可避免的會用到synchronized關(guān)鍵字。而AtomicInteger則通過一種線程安全的加減操作接口所禀。
AtomicInteger 主要方法如下:
- public final int get() //獲取當(dāng)前的值
- public final int getAndSet(int newValue)//獲取當(dāng)前的值方面,并設(shè)置新的值
- public final int getAndIncrement()//獲取當(dāng)前的值,并自增
- public final int getAndDecrement() //獲取當(dāng)前的值色徘,并自減
- public final int getAndAdd(int delta) //獲取當(dāng)前的值恭金,并加上預(yù)期的值
- public final int incrementAndGet() //自增后返回當(dāng)前值
- public final int decrementAndGet() //自減后返回當(dāng)前值
- public final int addAndGet(int delta) //加上預(yù)期值后返回當(dāng)前值
源碼解析
AtomicInteger 源碼如下:
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;
public AtomicInteger(int initialValue) {
value = initialValue;
}
public AtomicInteger() {
}
}
這里, unsafe是java提供的獲得對對象內(nèi)存地址訪問的類褂策,注釋已經(jīng)清楚的寫出了横腿,它的作用就是在更新操作時提供CAS(Compare And Swap)的作用。
valueOffset是用來記錄value本身在內(nèi)存的便宜地址的辙培,這個記錄蔑水,也主要是為了在更新操作在內(nèi)存中找到value的位置,方便比較扬蕊。
value是用來存儲整數(shù)的時間變量搀别,這里被聲明為volatile,就是為了保證在更新操作時尾抑,當(dāng)前線程可以拿到value最新的值(并發(fā)環(huán)境下歇父,value可能已經(jīng)被其他線程更新了)。
以getAndIncrement()方法為例再愈,代碼如下:
/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
public final int get() {
return value;
}
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return true if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}