nbsp; int pos = desc.size + FIRST_BUCKET_SIZE;
// 取出pos 的前导0
int zeroNumPos = Integer.numberOfLeadingZeros(pos);
// zeroNumFirst 为FIRST_BUCKET_SIZE 的前导0
// bucketInd 数据应该放到哪一个一维数组(篮子)里的
int bucketInd = zeroNumFirst - zeroNumPos;
// 00000000 00000000 00000000 00001000 第一个篮子满 8
// 00000000 00000000 00000000 00011000 第二个篮子满 8 + 16
// 00000000 00000000 00000000 00111000 第三个篮子满 8 + 16 + 32
// ... bucketInd其实通过前导0相减, 就是为了得出来当前第几个篮子是空的.
// 判断这个一维数组是否已经启用, 可能是第一次初始化
if (buckets.get(bucketInd) == null) {
//newLen 一维数组的长度, 取前一个数组长度 * 2
int newLen = 2 * buckets.get(bucketInd - 1).length();
// 设置失败也没关系, 只要有人初始化成功就行
buckets.compareAndSet(bucketInd, null,
new AtomicReferenceArray<E>(newLen));
}
// 在这个一位数组中,我在哪个位置
// 0x80000000是 10000000 00000000 00000000 00000000
// 这句话就是把上述111000, 第一个1变成了0, 得到011000, 即新值的位置.
int idx = (0x80000000>>>zeroNumPos) ^ pos;
// 通过bucketInd与idx来确定元素在二维数组中的位置
// 期望写入的时候, 该位置值是null, 如果非null, 说明其他线程已经写了, 则继续循环.
newd = new Descriptor<E>(desc.size + 1, new WriteDescriptor<E>(
buckets.get(bucketInd), idx, null, e));
// 循环cas设值
} while (!descriptor.compareAndSet(desc, newd));
descriptor.get().completeWrite();
}
/**
* Remove the last element in the vector.
*
* @return element removed
*/
public E pop_back() {
Descriptor<E> desc;
Descriptor<E> newd;
E elem;
do {
desc = descriptor.get();
desc.completeWrite();
int pos = desc.size + FIRST_BUCKET_SIZE - 1;
int bucketInd = Integer.numberOfLeadingZeros(FIRST_BUCKET_SIZE)
- Integer.numberOfLeadingZeros(pos);
int idx = Integer.highestOneBit(pos) ^ pos;
elem = buckets.get(bucketInd).get(idx);
&nb