CAS实现原子操作的三大问题:
ABA问题
所谓ABA问题,就是一个值原来是A,变成了B,又变回了A。这个时候使用CAS是检查不出变化的,但实际上却被更新了两次。ABA问题的解决思路是在变量前面追加上版本号或者时间戳。从JDK 1.5开始,JDK的atomic包里提供了一个类AtomicStampedReference类来解决ABA问题。
循环时间长开销大
CAS多与自旋结合。如果自旋CAS长时间不成功,会占用大量的CPU资源。解决思路是让JVM支持处理器提供的pause指令。pause指令能让自旋失败时cpu睡眠一小段时间再继续自旋,从而使得读操作的频率低很多,为解决内存顺序冲突而导致的CPU流水线重排的代价也会小很多。
只能保证一个共享变量的原子操作
这个问题你可能已经知道怎么解决了。有两种解决方案:
使用JDK 1.5开始就提供的AtomicReference类保证对象之间的原子性,把多个变量放到一个对象里面进行CAS操作;
使用锁。锁内的临界区代码可以保证只有当前线程能操作。