含义
CAS(CompareAndSwap) 即比较并替换,实现并发算法时常用到的一种技术。CAS操作包含三个操作数——内存位置、预期原值及新值。执行CAS操作的时候,将内存位置的值与预期原值比较,如果相匹配,那么处理器会自动将该位置值更新为新值,否则,处理器不做任何操作。
乐观锁的含义就是假设没有发生冲突,那么我正好可以进行某项操作,如果要是发生冲突呢,那我就重试直到成功,乐观锁最常见的就是CAS。
无论是ReenterLock内部的AQS,还是各种Atomic开头的原子类,内部都应用到了CAS
原理分析
以java.util.concurrent.atomic.***AtomicInteger***为例进行分析
/**
* An {@code int} value that may be updated atomically. See the
* {@link java.util.concurrent.atomic} package specification for
* description of the properties of atomic variables. An
* {@code AtomicInteger} is used in applications such as atomically
* incremented counters, and cannot be used as a replacement for an
* {@link java.lang.Integer}. However, this class does extend
* {@code Number} to allow uniform access by tools and utilities that
* deal with numerically-based classes.
*
* @since 1.5
* @author Doug Lea
*/
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex); }
}
private volatile int value;
/**
* Atomically increments by one the current value.
*
* @return the updated value
*/
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
...
}
- Unsafe是位于sun.misc包下的一个类,Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。
在jdk1.9中,对Usafe进行了删除,因此那些基于Usafe开发的框架慢慢的都死掉了。
- valueOffset是long类型的,此处代表的含义就是对象成员变量value相对对象内存地址的偏移量
valueOffset的赋值是放在static代码块中,也就是说类加载初始化的时候就执行一次,从而获取了value成员变量相对于当前对象内存地址的偏移量
- value变量使用volatile修饰保证了内存可见性,为后面的CAS提供了可能性。其实实际存储的值是放在value中的
- incrementAndGet方法剖析
调用链:
incrementAndGet() → unsafe.getAndAddInt(this, valueOffset, 1) + 1 → getAndAddInt(Object var1, long var2, int var4)
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
var1: 对应当前对象this; var2对应偏移量valueOffset;var4对应增量 1;
所以上面代码等价于
public final int getAndAddInt(Object this,long valueOffset,int 1){
int var5;
do {
var5 = this.getIntVolatile(this, valueOffset);
} while(!this.compareAndSwapInt(this, valueOffset