最近看AtomicIntegerArray,有一段代码把我搞懵了,请看:
static {
int scale = unsafe.arrayIndexScale(int[].class);
if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two");
shift = 31 - Integer.numberOfLeadingZeros(scale);
}
private long checkedByteOffset(int i) {
if (i < 0 || i >= array.length)
throw new IndexOutOfBoundsException("index " + i);
return byteOffset(i);
}
private static long byteOffset(int i) {
return ((long) i << shift) + base;
}
这里兜了一个大权来计算第i个元素的偏移量,我的猜想是为了性能考虑。看到这里真的感叹Doug Lea真牛逼,性能都是一点点抠出来的。6666666!!!
这里解释下 31 - Integer.numberOfLeadingZeros(scale),它的作用是把scale 转换为二进制左移的需要的位数。例如,4 相当于 << 2,8 相当于 << 3。
这里说明下为什么X % 2^n == X & 2^n -1。
首先 X 取模相当于要获得 X / 2^n 后留下一个比 2^n 小且最接近 2^n 的数。我们再来看下 X & 2^n -1,2^n - 1 转为二进制正好是一个比 2^n - 1 且每个位置都是1的二进制数,& X 相当于对X的低位上的1进行保留,所以留下来的数肯定是一个 <= 2^n - 1 的数。也就是 X % 2^n 的余数。
网友评论