CAS全称CompareAndSwap(比较并交换),是cpu的指令,调用时不涉及上下文的切换。Java中属于乐观锁的一种,具体流程如下图:
具体的实现使用的是Unsafe类去调用native修饰的compareAndSwap方法,4个字段分别是对象实例,字段偏移量,字段期望值,字段新值
可以通过反射的方式获取UnSafe类
通过传入变量获取偏移量
具体调用实例:
CAS存在的缺陷:
1、自旋长时间不成功会给cpu带来非常大的开销
2、只能保证一个共享变量原子操作
3、存在ABA问题
ABA问题:
当有多个线程对一个原子类进行操作的时候,某个线程在短时间内将原子类的值
A
修改为
B
,又马上将其修改为A
,此时其他线程不感知,还是会修改成功,具体过程如图:
ABA问题的解决方式可以通过添加版本号来解决,即每次修改数据时,比较版本号的值。每次修改完成后,版本号+1,通过这种方式来保证数据的唯一,解决ABA问题
在java.util.concurrent.atomic包里提供了一组原子操作类:
基本类型:AtomicInteger、AtomicLong、AtomicBoolean;
引用类型:AtomicReference、AtomicStampedRerence、AtomicMarkableReference;
数组类型:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
基本类型:AtomicInteger、AtomicLong、AtomicBoolean;
引用类型:AtomicReference、AtomicStampedRerence、AtomicMarkableReference;
数组类型:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray