Atomic 原子類詳解
1.AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference:基礎
// atomicInteger:整型原子類
AtomicInteger atomicInteger = new AtomicInteger(0);
atomicInteger.incrementAndGet();// 自增取新值
atomicInteger.decrementAndGet();// 自減取新值
atomicInteger.addAndGet(1);// 增加取新值
atomicInteger.getAndIncrement();// 自增取原值
atomicInteger.getAndDecrement();// 自減取原值
atomicInteger.getAndAdd(1);// 增加取原值
atomicInteger.getAndSet(10);// 設置取原值
atomicInteger.compareAndSet(10, 20);// 比較并設置,返回是否成功
// AtomicLong:長整型原子類,使用方式同上
// AtomicBoolean:布爾型原子類
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
atomicBoolean.set(true);// 設置
atomicBoolean.compareAndSet(false, true);// 比較并設置,返回是否成功
// AtomicReference:引用型原子類
AtomicReference<String> atomicReference = new AtomicReference<>("Hello");
atomicReference.set("World");// 設置
atomicReference.compareAndSet("World", "Hello Again");// 比較并設置,返回是否成功
2.AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray:數組
// AtomicIntegerArray:整型數組
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);
atomicIntegerArray.set(/*索引*/ 5, 10);// 設置
atomicIntegerArray.addAndGet(/*索引*/ 5, 5);// 增加取新值
atomicIntegerArray.compareAndSet(/*索引*/ 5, 10, 15);// 比較并設置,返回是否成功
// AtomicLongArray:長整型數組,使用方式同上
// AtomicReferenceArray:引用型數組
AtomicReferenceArray<String> atomicReferenceArray = new AtomicReferenceArray<>(10);
atomicReferenceArray.set(5, "Hello");// 設置
String newValue = atomicReferenceArray.getAndSet(5, "World");// 設置取原值
boolean success = atomicReferenceArray.compareAndSet(5, "Hello", "Hello Again");// 比較并設置
2.AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater:字段更新器
private static class MyClass {
// 字段要求:
// 1.volatile修飾
// 2.非static
// 3.public 或者有 get 和 set 方法
volatile int intValue;
}
public static void main(String[] args) {
MyClass myClass = new MyClass();
// 創建AtomicIntegerFieldUpdater
AtomicIntegerFieldUpdater<MyClass> intFieldUpdater =
AtomicIntegerFieldUpdater.newUpdater(MyClass.class, "intValue");
intFieldUpdater.set(myClass, 10);// 設置
int newValue = intFieldUpdater.incrementAndGet(myClass);// 自增取新值
// 更多方法,參考普通整型原子類...
// AtomicLongFieldUpdater:長整型使用方式同上
// AtomicReferenceFieldUpdater:引用型使用方式同上
}
3.AtomicStampedReference、AtomicMarkableReference:帶標志引用型,可用于避免ABA問題
// AtomicStampedReference:帶版本號
AtomicStampedReference<String> stampedReference = new AtomicStampedReference<>("Hello", 0);
boolean success = stampedReference.compareAndSet(/*原值*/ "Hello", "World", /*原標志*/ 0, 1);// 比較并設置,返回是否成功
stampedReference.getReference();// 取引用
stampedReference.getStamp();// 取標志
// AtomicMarkableReference:帶布爾值
AtomicMarkableReference<String> markableReference = new AtomicMarkableReference<>("Hello", false);
// 原子性地更新引用和標記
boolean markSuccess = markableReference.compareAndSet(/*原值*/ "Hello", "World", /*原標志*/ false, true);// 比較并設置,返回是否成功
markableReference.getReference();// 取引用
markableReference.isMarked();// 取標志
4.LongAdder、DoubleAdder、LongAccumulator、DoubleAccumulator:累加器
原理:LongAdder在內部維護一個數組,當多個線程嘗試同時修改時,會分散到不同的數組中進行更新。在獲取結果時,將所有數組的值相加得到總和。
優點:減少并發修改時的CAS競爭,高并發場景下性能優于AtomicLong
缺點:如果計算總和期間有線程修改,此次修改可能不會計入這次計算,所以不適合需要精確計算的場景。
// LongAdder:長整型累加器
LongAdder adder = new LongAdder();
adder.add(10);// 增加
adder.increment(); // 自增
adder.sum()// 取總和
adder.reset();// 重置為0
// DoubleAdder:小數型累加器,使用方式同上
// LongAccumulator:長整型自定累加器,使用乘法累加
LongAccumulator accumulator = new LongAccumulator((/*當前值*/ x, /*新值*/ y) -> x * y, /*初始值*/ 1L);
accumulator.accumulate(2); // 計算 accumulator = 1 * 2 = 2
accumulator.accumulate(3); // 計算 accumulator = 2 * 3 = 6
accumulator.get()// 取總和
accumulator.reset();// 重置為初始值
// DoubleAccumulator:小數型自定累加器,使用方式同上
浙公網安備 33010602011771號