LongAddr简单剖析
背景
LongAddr是AtomicLong的增强类,主要用于超高并发情况下的计数问题,建议在超高并发的情况下直接使用该类替代原有的AtomicLong。
实现原理
与ConcurrentHashMap类似,LongAddr主要采用的是分段技术,通过把一个Long拆分为多个Cell,可以大大提高计数时的写入效率。相对的,如果要获取得到的值,则需要所有Cell求和,其效率较普通Long类型更低。总的来说,LongAddr适用于写多读少的高并发场景。
以伪代码形式表示LongAddr的源码逻辑
void add(long val)
//首先尝试直接将值通过cas的方式写入base中,如果成功则不需要调用cell的逻辑,在低并发情况下就不需要引入cell这种重量级技术
if (cas(base, base.val, base.val + val)) {
return;
} else {
//尝试将值通过cas方式更新至目标cell中
if (cas(targetCell, targetCell.val, targetCell.val + val)) {
return;
} else {
//如果未初始化probe参数,则进行初始化
if (probe == null) {
initProbe();
//如果cells[]未初始化,则将整个数组初始化为2,并填入当前target的cell
} else if (cells == null) {
cells = new cell[2];
cell[target] = new Cell();
//如果cells[target] == null,则需要初始化cells[target]
} else if (targetCell == null) {
cell[target] == new Cell();
//以上都满足,但是仍然cas失败,说明冲突较为密集,对probe所对应的cell进行重新hash
} else {
current.probe = probe.newVal;
reahshFlag = true;
}
//再次尝试添加至cell中
if (cas(targetCell, targetCell.val, targetCell.val + val)) {
return;
//仍然添加失败,则对cell进行扩容
} else {
cells = new cell[cells.length * 2];//扩容的总大小小于CPU数量
}
}
}