CAS 有什么问题?如何解决?

ABA问题

在并发环境下,存在ABA问题,即在修改数据时,尽管最初看到的值是A,但在操作过程中可能出现了A变为B,然后又变回A的情况。虽然数据看起来没有变化,但实际上已经发生了变化。

如何解决ABA问题?

  • 引入版本号

每次修改变量时,都在该变量的版本号上加1。这样,即使发生了A->B->A的情况,尽管A的值没有变化,但其版本号已经发生变化。通过检查版本号,就能发现此时的A已经被修改过了。类似于乐观锁的版本号,这种做法可以为数据引入一种实效性的验证。

Java提供了AtomicStampedReference类,其compareAndSet方法首先检查当前对象引用值是否等于预期引用,并且当前的标志(Stamp)是否等于预期标志。如果全部相等,则以原子方式将引用值和标志的值更新为给定的更新值。

循环性能开销

自旋CAS如果一直循环执行且不成功,会给CPU带来巨大的执行开销。

如何解决循环性能开销问题?

在Java中,许多使用自旋CAS的场景会限制自旋的次数。超过一定次数后停止自旋,避免无限循环造成巨大的性能开销。

仅保证单个变量的原子操作

CAS仅保证对单个变量执行操作的原子性,对于多个变量的操作,CAS无法直接保证原子性。

如何解决仅保证单个变量的原子操作问题?

  • 可以考虑使用锁来保证操作的原子性。
  • 可以考虑将多个变量合并为一个对象,并使用AtomicReference来保证操作的原子性。

标签: java, Java面试题, Java问题合集, Java编程, Java问题精选, Java常见问题