前言
java 從jdk 1.5 開始提供了 java.util.concurrent.atomic包,這個包中原子操作類
提供了一種用法簡單,性能高效,線程安全地更新一個變量的方式。
因為變量有很多種,是以在automic包中提供了13類,屬于4種類型的原子更新方式“
- 原子更新基本類型
- 原子更新數組
- 原子更新引用
- 原子更新屬性(字段)
1.原子更新基本類型類
AtomicBoolean :原子更新布爾類型
AtomicInteger:原子更新整形
AtomicLong:原子更新長整型
以上三個類方法幾乎一摸一樣,是以學習一個就能知道其它的怎麼調用了,這裡以 AtomicInteger 進行解釋
public final int addAndGet(int delta). 以原子的方式将輸入的數值與執行個體中值(AtomicInteger 中的Value)相加并傳回結果。
public final boolean compareAndSet(int expect, int update) ,如果輸入的數值等于預期值,則以原子的方式将該值設定為輸入值
public final int getAndIncrement() 以原子的方式将目前值加 1.注意傳回的是自增前的值
public final void lazySet(int newValue) 。最終會設定成newValue,使用lazySet 設定值後,可能會導緻其他線程在之後一小段時間内還是可以讀到舊
的值。
public final int getAndSet(int newValue) :以原子的方式設定為newValue的值,并傳回舊值
代碼清單
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerTest {
static AtomicInteger atomicInteger = new AtomicInteger(1);
public static void main(String[] args) {
System.out.println(atomicInteger.getAndIncrement());
System.out.println(atomicInteger.get());
}
}
輸出結果如下:
1
2
Process finished with exit code 0
那麼getAndInsrement 是如何實作原子操作的呢?
在jdk1.7中,AtomicInteger的getAndIncrement是這樣的:
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
而在jdk1.8中,是這樣的:
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
本文使用jdk 1.7 進行分析
unsafe源碼
public final native boolean compareAndSwapObject(Object o, long offset, Object expected, Object x);
public final native boolean compareAndSwapInt(Object o, long offset, Object expected, Object x);
public final native boolean compareAndSwapLong(Object o, long offset, Object expected, Object x);