Atomic 原子类详解

1.AtomicIntegerAtomicLongAtomicBooleanAtomicReference:基础

// 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.AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray:数组

// 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.AtomicIntegerFieldUpdaterAtomicLongFieldUpdaterAtomicReferenceFieldUpdater:字段更新器

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.AtomicStampedReferenceAtomicMarkableReference:带标志引用型,可用于避免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.LongAdderDoubleAdderLongAccumulatorDoubleAccumulator:累加器

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

 

posted @ 2024-04-29 02:02  Yfeil  阅读(3)  评论(0编辑  收藏  举报