并发编程灵魂拷问系列之如何理解CAS


并发编程灵魂拷问系列之如何理解CAS

什么是CAS

CAS,compare And set/swap等,他底层的硬件级别操作(CPU指令cmpxchg)来保证一定是原子性操作,让同一时间只能有一个线程执行CAS操作,在此时间其他线程执行CAS会失败。java里经常使用unsafe类来执行CAS操作

CAS有三个参数:当前值A、内存值V、修改的新值B

  • 如果A和V相等,则把内存值V修改成新值B
  • 如果A和V不相等,要么重试,要么放弃更新

为什么要使用CAS呢

  • synchronized关键字每次都需要使用锁来保证同一时间只有一个线程执行操作
  • CAS允许多个线程同时操作共享数据,但是同一时间只能有一个线程执行CAS操作,在很多情况下比synchronized更加高效,例如 对一个值进行累加 这样的操作

AtomicLong等底层使用了CAS,但是更推荐使用LongAdder,性能更高(数组来分散目标值减少自旋重试)

CAS的缺点

  • 无法解决ABA的问题(共享变量从A -> B -> A),需要加一个版本号
  • 循环时间长导致资源消耗
  • 循环执行CAS操作不成功会陷入自旋而耗费cpu资源,锁竞争激烈的场景更倾向于使用重量级锁

解决ABA问题,可以使用结合 乐观锁 的机制,例如Java中的 AtomicStampedReference

使用场景

  1. 如果高并发执行时间久 ,用SYN好, 因为SYN底层用了wait() 阻塞后是不消耗CPU资源的
  2. 如果锁竞争不激烈说明自旋不严重,此时用CAS。

【参考链接】:
1:由浅入深讲解JUC下 CAS + Lock
2:Java中的锁原理、锁优化、CAS、AQS详解
3:【对线面试官】 CAS


评论
  目录