背景知识:
- sun.misc.Unsafe 类的运用,参见 http://ifeve.com/sun-misc-unsafe/
介绍:
AtomicXXXArray 包括AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray 三个主要类别,是对不同类型数组进行一个原子操作实现。实现方式为CAS
实现原理:
类在初始化时获取数组在起始位置以及偏移量
static {
//获取数组的元素所占空间大小,即比例因子
int scale = unsafe.arrayIndexScale(int[].class);
//判断其必须为2的指数倍
if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two");
//获取该比例因子二进制中1 在第几位,(十进制)4 = (二进制)100,故计算出来的shift 为 3
shift = 31 - Integer.numberOfLeadingZeros(scale);
}
通过shift及base 查找下标为 i 的偏移量
private long checkedByteOffset(int i) {
if (i < 0 || i >= array.length)
throw new IndexOutOfBoundsException("index " + i);
return byteOffset(i);
}
//可以证明 i * scale + base == i << shift + base
private static long byteOffset(int i) {
return ((long) i << shift) + base;
}
获取到偏移量,便可以通过
unsafe.getIntVolatile(array, offset);
来获取到下标 i 的值了。
根据数组和偏移量,便可根据CAS方式进行数据的更新了,CAS实现类似于AtomicBoolean