Java的基础学习:CAS是什么?

CAS(Compare And Swap)

什么是原子操作?如何实现原子操作?
答:要么都完成,要么都不完成--- 他们是不可以分割的,就是原子操作
比如:synchronized 包裹的内容就是原子操作

但是,synchronized 就是抢夺锁,这是一个很重的操作.所以就引进CAS(Compare and swap)
现代CPU 将 Compare And Swap打包成一个原子指令

CAS的原理

比如: 有A ,B,C 三个线程执行 count++的操作

  1. A线程:记录count 初始值, 完成++操作后, 执行 写入操作的时候: 先Compare( 比较初始值是否变化)--> 没有变化 则(Swap:替换). A线程结束
  2. B 线程: 完成++操作后, 执行 写入操作的时候: 先Compare( 比较初始值是否变化)--> 变化则以变化后的值为初始值. 继续循环
  3. C 等线程也是B这样的循环.直到结束.
引申的话题
 `CAS` 是乐观锁: 每次执行都是进行,直到最后才决定swap.

 synchronized 是悲观锁: 总有"刁民想害朕",只有真的获取锁资源才会执行.

CAS的优势

synchronized 涉及上下文切换,资源消耗大. 所以CAS 乐观锁的性能更好

CAS的不足

问题1:ABA 问题
假设:线程1 和线程2
线程1的操作: A---设置-->B , 最后做compare and swap的时候:
if 初始值A ,则设置成B
线程2的操作: A--->C--->A 并且线程2的更早执行.
如此,造成了明明修改了.但是线程1不知道

解决ABA 的思路: 在变量前面追加版本号,每次变量更新版本就会更新. 当swap的时候,同时比较值和版本号

比如:AtomicMarkableReference,AtomicStampedReference
AtomicMarkableReference: 关心有没有动过(bool)
AtomicStampedReference:关系修改的次数(count)

问题2:开销 问题
因为自旋的原因,对CPU 的执行有大开销

问题3: 只能保证一个共享变量的原子操作
当多个字段改变的原子操作的时候有问题

解决一个共享变量的原子操作: 将多个共享变量合并成一个共享变量进行CAS

比如: AtomicReference, 可以把多个变量组合在一个对象里面

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容