CAS的原理及其带来的问题!

CAS的原理及其带来的问题!

尼采
2023-01-07 / 0 评论 / 170 阅读 / 正在检测是否收录...

CAS原理:

CAS全称Compare and Swap,比较并交换,主要是通过处理器的指令来保证操作的原子性.
CAS的思想比较简单,主要涉及到三个值:

  1. 当前内存值V
  2. 预期值(旧的内存值)A
  3. 即将更新的内存值B
    当执行CAS指令时,只有当内存值V等于预期值A时,才会将内存值V修改为更新值B,否则就不会执行更新操作。

CAS主要使用在一些需要上锁的场景充当乐观锁解决方案,一般在一些简单且要上锁的操作但又不想引入锁场景,这时候来使用CAS代替锁。

CAS有什么缺点:

1.ABA问题:

  ABA问题是指有一个线程t1在进行CAS操作时,其他线程t2将变量A改成了B,然后又将其改成A,这时候t1发现A并没有改变,因此进行了交换操作,由于在交换操作进行前变量A其实是有变化的,只不过最终又修改回A了,此A非彼A,这时候进行交换操作在一些业务场景下很可能要出问题,要解决ABA问题有2种方案。
方案一:
在对变量进行操作的时候给变量加一个版本号,每次对变量操作都将版本号加1,常见在数据库的乐观锁中可见。
方案二:
Java提供了相应的原子引用类AtomicStampedReference,他加入了预期标志和更新后标志两个字段,更新时不光检查值,还要检查当前的标志是否等于预期标志,全部相等的话才会更新。

2.自旋带来的消耗:

  CAS自旋如果很长时间都不成功,这会给CPU带来很大的开销。
解决方案:
1、代码层面破坏掉for循坏,设置合适的循环次数。
2、使用JVM能支持处理器提供的pause指令来提升效率,它可以延迟流水线执行指令,避免消耗过多CPU资源。

3.CAS只能单变量:

  对于一个共享变量,可以使用CAS方式来保证原子操作,但是当多个共享变量时,那就无法使用CAS来保证原子性。JDK1.5开始,提供了AtomicReference类来保证引用对象之前的原子性,就可以把多个变量放在一个对象里来进行CAS操作。

在JDK1.5中新增的java.util.concurrent(JUC),就是建立在CAS之上的,一般来说CAS这种乐观锁适合读多写少的场景。

2

评论 (0)

取消