jdk17-LongAddr 类increment()方法注释说明
increment() 方法如下:
/**
* Equivalent to {@code add(1)}.
*/
public void increment() {
add(1L);
}
成员变量如下
/** Number of CPUS, to place bound on table size */
static final int NCPU = Runtime.getRuntime().availableProcessors();
/**
* Table of cells. When non-null, size is a power of 2.
*/
transient volatile Cell[] cells;
/**
* Base value, used mainly when there is no contention, but also as
* a fallback during table initialization races. Updated via CAS.
*/
transient volatile long base;
/**
* Spinlock (locked via CAS) used when resizing and/or creating Cells.
*/
transient volatile int cellsBusy;
/**
* 使用 VarHandle 对实例的属性进行CAS操作
*/
final boolean casBase(long cmp, long val) {
return BASE.weakCompareAndSetRelease(this, cmp, val);
}
private static final VarHandle BASE;
private static final VarHandle CELLSBUSY;
private static final VarHandle THREAD_PROBE;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
BASE = l.findVarHandle(Striped64.class,
"base", long.class);
CELLSBUSY = l.findVarHandle(Striped64.class,
"cellsBusy", int.class);
l = java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<>() {
public MethodHandles.Lookup run() {
try {
return MethodHandles.privateLookupIn(Thread.class, MethodHandles.lookup());
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}});
THREAD_PROBE = l.findVarHandle(Thread.class,
"threadLocalRandomProbe", int.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}
探测线程的hash值,如果threadLocalRandomSeed 初始化了,那么该值就非0
int threadLocalRandomProbe;
add() 方法如下:
/**
* Adds the given value.
*
* @param x the value to add
*/
public void add(long x) {
Cell[] cs; long b, v; int m; Cell c;
/**
* 这里优先判断了cell数组是否为空,
* 之后才判断base字段的cas累加
* 意味着如果线程不发生竞争,cell数组一直为空,那么所有的累加操作都会累加到base上
* 而一旦发生过一次竞争导致cell数组不为空,那么所有的累加操作都会优先作用于数组中的对象上
*/
if ((cs = cells) != null || !casBase(b = base, b + x)) {
// 获取线程的hash值,如果threadLocalRandomSeed 初始化了,那么该值就非0
int index = getProbe();
/**
* 这个字段是用来标识在对cell数组中的对象进行累加操作时是否发生了竞争
* 如果发生了竞争,那么在longAccumulate方法中会多进行一次rehash的自旋
* 这个在后面的方法中详细说明,这里先有个印象
* true表示未发生竞争
*/
boolean uncontended = true;
// 如果cell数组为空或者长度为0则直接进入主逻辑方法
if (cs == null || (m = cs.length - 1) < 0 ||
/**
* 这里的index 是线程的hash值
* hash值与(数组长度-1)进行位与操作后得到对应的数组下标
* 判断该元素是否为空,如果不为空那么就会尝试累加
* 否则进入主逻辑方法
*/
(c = cs[index & m]) == null ||
/**
* 对数组下标的元素进行cas累加,如果成功了,那么就可以直接返回
* 否则进入主逻辑方法
*/
!(uncontended = c.cas(v = c.value, v + x)))
longAccumulate(x, null, uncontended, index);
}
}