AtomicInteger 原始碼分析
阿新 • • 發佈:2018-12-02
AtomicInteger
支援原子更新的 int 值。
建立例項
/** * 可原子更新的 int 值 */ private volatile int value; /** * 建立初始值為 initialValue 的新 AtomicInteger 例項 */ public AtomicInteger(int initialValue) { value = initialValue; } /** * 建立初始值為 0 的新 AtomicInteger 例項 */ public AtomicInteger() { }
讀取值
/**
* 讀取值
* with memory effects as specified by {@link VarHandle#getVolatile}.
*/
public final int get() {
return value;
}
以原子方式將當前值加 1,並返回舊值
/** * 以原子方式將當前值加 1,並返回舊值。 * with memory effects as specified by {@link VarHandle#getAndAdd}. */ public final int getAndIncrement() { return U.getAndAddInt(this, AtomicInteger.VALUE, 1); } Unsafe# /** * 1)原子地將給定的值累加到當前值、或指定索引為 offset 的陣列元素上。 */ @HotSpotIntrinsicCandidate public int getAndAddInt(Object o, long offset, int delta) { int v; do { // 以 volatile 的方式讀取值 v = getIntVolatile(o, offset); } while (!weakCompareAndSetInt(o, offset, v, v + delta)); // 返回舊值 return v; } @HotSpotIntrinsicCandidate public boolean weakCompareAndSetInt(Object o, long offset, int expected, int x) { return compareAndSetInt(o, offset, expected, x); } /** * 如果當前值是 expected,則將目標值更新為 x,該操作具有 volatile 讀和寫記憶體語義。 * <p>This operation has memory semantics of a {@code volatile} read * and write. Corresponds to C11 atomic_compare_exchange_strong. */ @HotSpotIntrinsicCandidate public native boolean compareAndSetInt(Object o, long offset, int expected, int x);
以原子方式寫入新值,並返回舊值
/**
* 以原子方式寫入新值,並返回舊值
* with memory effects as specified by {@link VarHandle#getAndSet}.
*/
public final int getAndSet(int newValue) {
return U.getAndSetInt(this, AtomicInteger.VALUE, newValue);
}
以原子方式將當前值減 1,並返回舊值
/** * 以原子方式將當前值減 1,並返回舊值 * with memory effects as specified by {@link VarHandle#getAndAdd}. */ public final int getAndDecrement() { return U.getAndAddInt(this, AtomicInteger.VALUE, -1); }
以原子方式將給定值與當前值相加,並返回舊值
/**
* 以原子方式將給定值與當前值相加,並返回舊值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int getAndAdd(int delta) {
return U.getAndAddInt(this, AtomicInteger.VALUE, delta);
}
原子更新當前值為函式式介面 updateFunction 的計算值,並返回舊值
/**
* 原子更新當前值為函式式介面 updateFunction 的計算值,並返回舊值。
*/
public final int getAndUpdate(IntUnaryOperator updateFunction) {
// 讀取舊值
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
// 計算新值
next = updateFunction.applyAsInt(prev);
}
// 原子更新值,如果成功則返回舊值
if (weakCompareAndSetVolatile(prev, next)) {
return prev;
}
// 更新失敗則重新讀取舊值,如果出現 ABA 問題,則不會重新計算
haveNext = prev == (prev = get());
}
}
原子更新當前值為函式式介面 accumulatorFunction 的計算值,並返回舊值
/**
* 原子更新當前值為函式式介面 accumulatorFunction 的計算值,並返回舊值
*/
public final int getAndAccumulate(int x,
IntBinaryOperator accumulatorFunction) {
// 讀取舊值
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
// 基於舊值和 x 計算新值
next = accumulatorFunction.applyAsInt(prev, x);
}
// 原子更新舊值
if (weakCompareAndSetVolatile(prev, next)) {
return prev;
}
haveNext = prev == (prev = get());
}
}
以原子方式將當前值加 1,並返回新值
/**
* 以原子方式將當前值加 1,並返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int incrementAndGet() {
return U.getAndAddInt(this, AtomicInteger.VALUE, 1) + 1;
}
以原子方式將當前值減 1,並返回新值
/**
* 以原子方式將當前值減 1,並返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int decrementAndGet() {
return U.getAndAddInt(this, AtomicInteger.VALUE, -1) - 1;
}
以原子方式將給定值與當前值相加,並返回新值
/**
* 以原子方式將給定值與當前值相加,並返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int addAndGet(int delta) {
return U.getAndAddInt(this, AtomicInteger.VALUE, delta) + delta;
}
以原子方式更新值【新值通過函式式介面計算得到,引數為舊值】,並返回新值
/**
* 以原子方式更新值【新值通過函式式介面計算得到,引數為舊值】,並返回新值。
*/
public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
next = updateFunction.applyAsInt(prev);
}
if (weakCompareAndSetVolatile(prev, next)) {
return next;
}
haveNext = prev == (prev = get());
}
}
以原子方式更新值【新值通過函式式介面計算得到,引數為舊值和參考更新值】,並返回新值
/**
* 以原子方式更新值【新值通過函式式介面計算得到,引數為舊值和參考更新值】,並返回新值
*/
public final int accumulateAndGet(int x,
IntBinaryOperator accumulatorFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
next = accumulatorFunction.applyAsInt(prev, x);
}
if (weakCompareAndSetVolatile(prev, next)) {
return next;
}
haveNext = prev == (prev = get());
}
}