5 CAS详解

本文探讨了Java中的原子操作,包括CAS实现的问题(ABA问题、循环时间开销和共享变量原子性),介绍了Jdk中的AtomicInteger、AtomicIntegerArray等原子类,以及LongAdder和新添加的LongAccumulator等并发优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1 原子操作

2 CAS 实现原子操作的三大问题

2.1 ABA问题

2.2 循环时间长开销大

2.3 仅能保证一个共享变量的原子操作

3 Jdk 中相关原子操作类

3.1 AtomicInteger

3.2 AtomicIntegerArray

3.3 更新引用类型

3.3.4 AtomicReference

3.3.5 AtomicStampedReference

3.3.6 AtomicMarkableReference

3.4 原子更新字段类

3.4.1 AtomicIntegerFieldUpdater

3.4.2 AtomicLongFieldUpdater

3.4.3 AtomicReferenceFieldUpdater

3.5 LongAdder

3.6 其它新增

3.6.1 LongAccumulator

3.6.2 DoubleAdder

3.6.3 DoubleAccumulator


1 原子操作

        假定有两个操作 A 和 B,如果从执行 A 的线程来看,当另一个线程执行 B 时,要么将 B全部执行完,要么完全不执行 B,执行 B 的线程看 A 的操作也是一样的,那么 A和 B 对彼此来说是原子的

        synchronized 关键字是基于阻塞的锁机制,但有几个问题:

                阻塞的线程优先级很高

                锁的线程一直不释放锁

                死锁之类的情况

                锁机制是一种粒度比较大的机制

        为了解决这个问题,Java 提供了 Atomic 系列的原子操作类

2 CAS 实现原子操作的三大问题

2.1 ABA问题

        如果一个值原来是 A,变成了 B,又变成了 A

        ABA 问题的解决思路就是使用版本号  A→B→A 就会变成 1A→2B→3A

2.2 循环时间长开销大

        自旋 CAS 如果长时间不成功,会给 CPU 带来非常大的执行开销

2.3 仅能保证一个共享变量的原子操作

        多个共享变量操作时,循环 CAS 就无法保证操作的原子性

                如:共享变量 i=2,j=3,通过CAS分别操作i j,可能会引发问题;解决:加锁,将ij绑在一起操作;JDK 提供了 AtomicReference 类来保证引用对象之间的原子性,可以将多个变量放对象里操作

3 Jdk 中相关原子操作类

3.1 AtomicInteger

int addAndGet(int delta):原子相加

boolean compareAndSet(int expect,int update):输入的数值等于预期值,就进行原子赋值

int getAndIncrement():原子方式将当前值加 1,返回自增前的值

nt getAndSet(int newValue):原子方式设置为 newValue 的值返回旧值

3.2 AtomicIntegerArray

原子的方式更新数组里的整型

int addAndGet(int i,int delta):原子方式执行 数组i值+delta

boolean compareAndSet(int i,int expect,int update):如果当前值=expect,则将数组i值=update

        AtomicIntegerArray会将数组复制一份,当AtomicIntegerArray对内部值进行修改时,不会影响原数组

3.3 更新引用类型

3.3.4 AtomicReference

原子更新引用类型

3.3.5 AtomicStampedReference

利用版本戳的形式记录了每次改变以后的版本号,这样就不会存在ABA问题

3.3.6 AtomicMarkableReference

原子更新带有标记位的引用类型

3.4 原子更新字段类

3.4.1 AtomicIntegerFieldUpdater

原子更新整型字段

3.4.2 AtomicLongFieldUpdater

原子更新长整型字段

3.4.3 AtomicReferenceFieldUpdater

原子更新引用类型字段

3.5 LongAdder

        AtomicLong利用底层CAS操作提供并发性,调用unsafe.getAndAddLong方法(采用自旋方式不断更新目标值,直到更新成功)

        为了解决高并发环境下AtomicLong的自旋瓶颈问题

        采取思想:自增场景下,将对value的热点操作进行分散,记录每个线程对value的操作到arr中,最后进行累加

        线程数越多,并发操作数越大,LongAdder的性能越优;线程数较小,AtomicLong操作更优

3.6 其它新增

3.6.1 LongAccumulator

LongAdder的增强版,LongAdder仅提供数值加减,LongAccumulator提供自定义函数

3.6.2 DoubleAdder

Double类型的累加原子操作

3.6.3 DoubleAccumulator

Double类型的累加原子操作,支持自定义函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值