浅谈AtomicInteger底层实现原理

博客围绕Java中CAS关键字展开,介绍AtomicInteger基于CAS技术实现原子性操作。阐述了CAS在数据库索引一致性方面的使用,推荐用Variable Handle API实现。同时指出CAS有失败重试消耗CPU及ABA问题,Java提供AtomicStampedReference解决ABA问题,开发者多间接享受其好处。

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

前言

嗯,这个对于多线程记数很重要


关键字

CAS,乐观锁

一、定义

AtomicIntger 是对 int 类型的一个封装,提供原子性的访问和更新操作,其原子性操作的实现是基于 CAS(compare-and-swap)技术。

二、使用及场景

关于 CAS 的使用,在数据库产品中,为保证索引的一致性,一个常见的选择是,保证只有一个线程能够排他性地修改一个索引分区,
一般来说,我们进行的类似 CAS 操作,可以并且推荐使用 Variable Handle API 去实现,其提供了精细粒度的公共底层 API。我这里强调公共,是因为其 API 不会像内部 API 那样,发生不可预测的修改,这一点提供了对于未来产品维护和升级的基础保障,坦白说,很多额外工作量,都是源于我们使用了 Hack 而非 Solution 的方式解决问题。

CAS 也并不是没有副作用,试想,其常用的失败重试机制,隐含着一个假设,即竞争情况是短暂的。大多数应用场景中,确实大部分重试只会发生一次就获得了成功,但是总是有意外情况,所以在有需要的时候,还是要考虑限制自旋的次数,以免过度消耗 CPU。

另外一个就是著名的ABA问题,这是通常只在 lock-free 算法下暴露的问题。我前面说过 CAS 是在更新时比较前值,如果对方只是恰好相同,例如期间发生了 A -> B -> A 的更新,仅仅判断数值是 A,可能导致不合理的修改操作。针对这种情况,Java 提供了 AtomicStampedReference 工具类,通过为引用建立类似版本号(stamp)的方式,来保证 CAS 的正确性,具体用法请参考这里的介绍。

前面介绍了 CAS 的场景与实现,幸运的是,大多数情况下,Java 开发者并不需要直接利用 CAS 代码去实现线程安全容器等,更多是通过并发包等间接享受到 lock-free 机制在扩展性上的好处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值