并发之CAS原子操作的三大问题

文章目录

  • ABA 问题
  • 循环时间长开销大
  • 循环时间长开销大


ABA 问题

因为CAS需要在操作值的时候,检查值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。
ABA问题的解决思路就是使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号加1,那么A→B→A就会变成1A→2B→3A。

假设有A和B两人之间存在某种关系。在某一阶段,A对B持有某种态度,比如最开始处于友好(a阶段)。然后在接下来的阶段,A对B的态度发生了改变,变得很疏远(b阶段)。最后,又回到了之前的友好态度(a阶段)。
尽管最终态度回到了最初的状态,但在中间发生了一些变化。这就好比中国古代的“尔虞我诈”故事,当中有许多人在相互转变立场,最终结果似乎是“回到了原点”,但实际上中间的变化可能会对结果产生重大影响。
在并发编程中,ABA问题可能会导致数据的意外修改,就像在这个人际关系的例子中一样。因此,在并发操作中,我们需要注意和处理ABA问题,以确保数据的一致性和准确性。

循环时间长开销大

自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。

循环时间长开销大

当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁。

还有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。比如,有两个共享变量a=2,j=q,合并一下aj=2q,然后用CAS来操作aj。从Java1.5开始,JDK提供了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对象里来进行CAS操作。

你可能感兴趣的:(并发,java,并发)