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:小數型自定累加器,使用方式同上