CAS还能这样理解??

1.CAS全称

全称:compare and swap,比较并交换。
虽然翻译过来是[比较并交换],但它是一个原子性的操作,对应到CPU指令为cmpxchg。

CAS还能这样理解??_第1张图片

2.通俗理解CAS

  1. CAS 有三个操作数:当前值A、内存值V、要修改的新值B。
  2. 假设 当前值A 跟 内存值V 相等,那就将内存值V 改成B。
  3. 假设 当前值A 跟 内存值V 不相等,要么就重试,要么就放弃更新。
  4. 将当前值与内存值进行对比,判断是否有被修改过,这就是CAS的核心。

3.CAS的问题

CAS有个缺点就是会带来ABA的问题。
从CAS更新的时候,我们可以发现它只比对当前值和内存值是否相等,这会带来个问题,下面我举例说明下:

  1. 假设线程A读到当前值是10,可能线程B把值修改为100,然后线程C又把值修改为10。
  2. 等到线程A拿到执行权时,因为当前值和内存值是一致的,线程A是可以修改的!
  3. 站在线程A的角度来说,这个值是从未被修改的 。
  4. 这是不合理的,因为我们从上帝的角度来看,这个变量已经被线程B和线程C修改过了。

4.解决ABA问题

要解决ABA的问题,Java也提供了AtomicStampedReference类供我们用,说白了就是加了个版本,比对的就是内存值+版本是否一致。

疑问:

为什么阿里巴巴开发手册提及到推荐使用 LongAdder 对象,比AtomicLong 性能更好(减少乐观锁的重试次数)?

原因:

因为AtomicLong做累加的时候实际上就是多个线程操作同一个目标资源。

在高并发时,只有一个线程是执行成功的,其他的线程都会失败,不断自旋(重试),自旋会成为瓶颈。

而LongAdder的思想就是把要操作的目标资源 分散,到数组Cell中。

每个线程对自己的 Cell 变量的 value 进行原子操作,大大降低了失败的次数。

这就是为什么在高并发场景下,推荐使用LongAdder 的原因。

对于LongAdder 的详解在这篇文章!!!--->为什么阿里推荐 LongAdder ,不推荐 AtomicLong ??

你可能感兴趣的:(java,jvm,开发语言,spring,服务器,mysql,tomcat)