• 基础 | 并发编程 - [原子类]


    §1 总览

    原子类大多在包 java.util.concurrent.atomic 下

    原子型基础型类型说明
    AtomicBooleanboolean基本
    AtomicIntegerint基本
    AtomicIntegerArrayint[]数组
    AtomicIntegerFieldUpdater
    AtomicLonglong基本
    AtomicLongArraylong[]数组
    AtomicLongFieldUpdater
    AtomicMarkableReference
    AtomicReferenceObject引用
    AtomicReferenceArrayObject[]数组
    AtomicReferenceFieldUpdater
    AtomicStampedReference
    DoubleAccumulator
    DoubleAdder
    LongAccumulator
    LongAdder

    通用 api

    • get()
      获取
    • getAndSet()
      获取并赋予新值,相当于 i=x
    • getAndIncrement()
      获取并自增,相当于 i++
    • getAndDecrement()
      获取并自减,相当于 i--
    • getAndAdd()
      获取并在原值基础上 + 差值,相当于 i+=x
    • compareAndSet()
      比较,如果相等就赋予新值

    §2 基本类型原子类

    基础数据类型原子类

    • AtomicBoolean,相当于 boolean
    • AtomicInteger,相当于 int
    • AtomicLong,相当于 long

    示例

    AtomicInteger atomicInteger = new AtomicInteger(10);
    atomicInteger.getAndIncrement();//相当于 i++
    
    • 1
    • 2

    §3 数组类型原子类

    数组数据类型原子类
    类似 基础数据类型原子类

    • AtomicBooleanArray,相当于 boolean[]
    • AtomicIntegerArray,相当于 int[]
    • AtomicLongArray,相当于 long[]

    §4 引用类型原子类

    引用类型原子类

    • AtomicReference
      相当于 Object
      常用于实现基于线程的自旋锁
      不能处理 ABA 问题
    • AtomicStamptReference
      AtomicReference 增加了版本信息
      常用于实现基于线程的自旋锁
      可以处理 ABA 问题
    • AtomicMarkableReference
      AtomicReference 增加了修改标记
      修改值前,应判断修改标记 isMarked()
      修改值时,应同步修改 修改标记compareAndSet(old, new, oldMark, !oldMark)
      可以处理 ABA 问题,相对于 AtomicStamptReference 只关心是否被改过,而不关心更改次数

    注意
    引用类型原子类只能 CAS 引用本身,而不是引用内部的字段值

    User user = new User();
    AtomicReference<User> atomicUser = new AtomicReference<>();
    atomicUser.set(user);
    atomicUser.compareAndSet(user,new User());
    
    • 1
    • 2
    • 3
    • 4

    §4 属性修改原子类

    • 用于对非线程安全的字段进行 线程安全 的修改
    • 基于反射实现
    • 被修改的字段必须被 public volatile 修饰

    包含下面三个类

    • AtomicIntegerFieldUpdater
    • AtomicLongFieldUpdater
    • AtomicReferenceFieldUpdater
    AtomicIntegerFieldUpdater<User> updater = 
    	AtomicIntegerFieldUpdater.newUpdater(User.class,"age");
    
    updater.getAndIncrement(user);
    
    • 1
    • 2
    • 3
    • 4

    §5 原子操作增强

    • DoublAccumulator
    • DoubleAdder
    • LongAccumulator
    • LongAdder

    应用场景
    适用于不要求实时精确,的基础数据累加

    • 点赞计数器
    • int[] 所有元素 ++

    AtomicLong 比较

    • 高并发场景下性能提高,减少 cas 消耗(大约一个数量级)
    • 不能保证实时精准

    LongAdderLongAccumulator 的区别

    初始值加值
    LongAdder只能是 0只能是 1
    LongAccumulator任意任意
    LongAdder adder = new LongAdder();
    adder.increment();
    adder.increment();
    System.out.println(adder.sum()); // 2
    
    LongAccumulator accumulator = new LongAccumulator((x,y)->x+y,0);
    accumulator.accumulate(1);
    accumulator.accumulate(2);
    System.out.println(accumulator.get()); // 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    源码
    详见 基础 | 并发编程 - [Striped64]

    §6 原子操作底层类

  • 相关阅读:
    Java的日期与时间java.util.TimeZone简介说明
    MES解决方案赋能「汽车改装行业」
    基于java冰球馆管理系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
    构建 Kubernetes Operator 的原则
    简单工厂模式
    flutter_gen依赖
    STM32CubeMX教程4 EXTI 按键外部中断
    Java高级---网络编程
    如何在 Endless OS 上安装 ONLYOFFICE 桌面编辑器 7.5
    安装MPICH并运行第一行代码
  • 原文地址:https://blog.csdn.net/ZEUS00456/article/details/126823407