标签:integer源码 api 方法 dad 源码 public nat long off
首先要知道CAS
Compare and Swap,即比较再交换;
区别于synchronouse同步锁的一种乐观锁(是一种无锁算法)
CAS有3个操作数,
当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做;
CAS是CPU级别的指令操作,上述操作是一步原子操作;
ABA问题
有可能value被改了,又被改回来了,那么CAS算法是无法发现value已经被修改过了,误认为没有被修改;
private volatile int value;
private static final long valueOffset;
// 通过unsafe对象,来进行native操作
private static final Unsafe unsafe = Unsafe.getUnsafe();
两个重要属性:
valueOffset
就是说:AtomicInteger对象,在创建完成之后,在内存中分配一片内存,其中此对象的每个属性相对于这片内存的偏移量就已经确定了;
valueOffset就是AtomicInteger对象的value属性在内存中的偏移量;
通过下面的Unsafe类的native方法,直接从内存中获取value的值;
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
我们要执行下面一系列操作时:
AtomicInteger i = new AtomicInteger(0);
int original =i.getAndAdd(3);
value
属性中;// 构造器
public AtomicInteger(int initialValue) {
value = initialValue;
}
getAndAdd
方法// 调用getAndAdd方法
private static final Unsafe unsafe = Unsafe.getUnsafe();
public final int getAndAdd(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta);
}
此方法会调用Unsafe类下的多个Native方法
getIntVolatile
和compareAndSwapInt
都是Unsafe类下的native方法;
getIntVolatile
:就是CAS中的根据内存地址,直接在内存级别获取当前旧值;
compareAndSwapInt
:就是CAS的比较修改的操作,修改成功,返回true,那么跳出循环;修改失败,继续尝试获取内存值,进行修改;
// 再调用Unsafe类下的getAndAddInt方法
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
// CAS操作
do {
/**
* var1:我们创建的AtomicInteger对象
* var2:valueOffset
* 就是找到此对象下,value属性在内存中的偏移量,在内存级别直接拿到value的值
*/
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
// 返回旧值
return var5;
}
与getAndAdd
类似
同样是调用unsafe对象下的unsafe.getAndAddInt(this, valueOffset, 1)
只不过delta直接传值为1;
标签:integer源码 api 方法 dad 源码 public nat long off
原文地址:https://www.cnblogs.com/mussessein/p/12635570.html