java的CAS原理
what:
CAS的全称是Compare and Swap,即比较并交换。比较的是当前内存中存储的值与预期原值,交换的是新值与内存中的值。这个操作是硬件层面的指令,因此能够保证原子性。Java通过JNI(本地方法调用)来使用这个原子操作,也是乐观锁最常用的机制。
CAS操作包含三个操作数——内存位置、预期原值和新值。在执行CAS操作时,先进行Compare操作,即比较内存位置的值与预期原值是否相等,若相等,则执行Swap操作将新值放入该内存位置。若不相等,则不进行Swap操作。demo如下:
UnSafe类中的重要方法,都是native的,是调用了底层操作系统的CAS指令,如下:
where(使用场景)
在Java的concurrent包中,有一种通用的实现方式,即CAS配合volatile来实现许多高并发类。
how(缺陷的解决方案):
1、ABA问题:
value初值为A,线程1读取到预期原值为A,线程2读取到预期原值为A,线程1通过CAS操作将A更新为B,再通过一次CAS操作将值更新为A,此时线程2进行CAS操作,在比较时发现预期原值A与当前内存位置的值A相同,则进行更新,但是此时value已经被更新过了,而不是原来那个A值了,这样会产生线程安全问题。
现在也有解决方案,在Java API中有一个类为AtomicStampedReference,该类在记录预期原值的同时还会记录标志,在比较时还会比较标志。
2、自旋时间长的情况下会导致很大开销。
若JVM支持pause指令,则可以解决此问题。pause指令有两个作用,第一是延迟流水线执行指令,使得CPU不会消耗太多执行时间;第二是避免在退出循环时因内存顺序冲突而引起CPU流水线被清空。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具