所有分类
  • 所有分类
  • 未分类

Java-CAS的原理和优缺点

简介

说明

本文介绍Java中的CAS的原理,优点和缺点。

CAS,Compare And Swap,即比较并交换。

CAS性能很高,适合于高并发场景。

CAS是JUC的基础

Doug lea大神在同步组件中大量使用CAS实现了Java多线程的并发操作,CAS是整个JUC(java.util.concurrent)的基石。

以下组件都用到了CAS

  • AQS同步组件
  • Atomic原子类操作
  • jdk8的ConcurrentHashMap使用CAS + Synchronized。

CAS原理

CAS是一种基于锁的操作,而且是乐观锁

CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。若内存地址里面的值和A的值是一样的,就将内存里面的值更新成B。

CAS是通过无限循环来获取数据的,一旦检测到冲突产生,就重试当前操作直到没有冲突。
若在第一轮循环中,a线程获取地址里面的值被b线程修改了,那么a线程自旋,直到某一次循环时地址里的值没有被修改。

CAS优点

CAS是乐观锁,且一直自旋等待锁,所以性能很高。

CAS缺点

CAS缺点有三个:CPU开销大;ABA问题;只能保证一个共享变量原子操作。

缺点说明解决方法
CPU开销大如果自旋CAS长时间地不成功,则会给CPU带来非常大的开销。        在JUC中有些地方就限制了CAS自旋的次数,例如BlockingQueue的SynchronousQueue。
ABA问题如果一个值原来是A,变成了B,然后又变成了A,在CAS检查时会发现没有改变,但实际它已经改变,这就是ABA问题。大部分情况下ABA问题不会影响程序并发的正确性。        每个变量都加上一个版本号,每次改变时加1,即A —> B —> A,变成1A —> 2B —> 3A。         Java提供了AtomicStampedReference来解决。AtomicStampedReference通过包装[E,Integer]的元组来对对象标记版本戳(stamp),从而避免ABA问题。
只能保证一个共享变量原子操作CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。        比如需要保证3个变量共同进行原子性的更新,就不得不使用Synchronized了。         还可以考虑使用AtomicReference来包装多个变量,通过这种方式来处理多个共享变量的情况。
3

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录