CAS定义
CAS全称:CompareAndSwap,比较并替换。
CAS操作包含3个操作数,内存位置V,期望值A,新值B。
如果内存位置的值和期望值匹配,那么处理器会自动将该位置的值更新。
否则处理器不做任何操作。
无论哪种情况,它都会在CAS指令之前,返回该位置的值。
怎样使用JDK提供CAS支持
java提供对CAS操作,具体在sum.misc.unsafe类下:
final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
参数解释:
参数var1:表示要操作的对象。
参数var2:表示要操作对象中属性地址的偏移量。
参数var4:表示需要修改数据的期望的值。
参数var5:表示需要修改为的新值。
CAS实现原理是什么?
CAS通过java native interface代码实现,允许java调用其它语言。compareAndSwap就是借助C语言来调用底层CPU的指令实现的。
这个CAS最终映射到cpu的指令是一个原子指令,实现比较并替换的操作。
现在计算机是多核的,怎么保证线程安全?
系统底层执行CAS操作的时候,会判断当前系统是否为多核心系统,如果是,就给总线加锁。
只有一个线程会对总线加锁成功,加锁成功之后会执行CAS操作,也就是说CAS的原子性是平台界别的。
什么是ABA问题?
CAS需要在操作值得时候检查下值有没有发生变化,如果没有变化则更新。
但是如果一个值原来是A,在CAS方法执行之前,就其他线程该成了B,然后又改回了A。
那么CAS执行方法检查的时候会发现它的值没有发生变化,实际却发生了变化。
ABA问题如何解决?
解决ABA问题的最好的方案就是给值加一个版本号,每次值变化,都会修改它的版本号。CAS操作时都去对比此版本号。
JAVA中ABA的解决办法?
AtomicStampedReference狐妖包含一个对象引用以及一个可以自动更新的整数Stamp的pari对象来解决ABA问题。
示例:
public boolean compareAndSet
(V expectedReference, //期望引用
V newReference, //新值引用
int expectedStamp, //期望引用的版本号
int newStamp //新值版本号