public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
我发现增量方法在循环块中起作用。为什么我们不能只计算一个没有任何循环的结果?它有什么意义?
如果另一个线程出现并更改了AtomicIntegerbetween int current = get()and的值compareAndSet(current, next),则compareAndSet调用将失败。使用循环可确保这种可能性永远不会发生。
如果compareAndSet另一个线程增加或以其他方式AtomicInteger在当前线程增加AtomicInteger
current = get()AtomicIntegernext = current + 1if(compareAndSet(current, next))在第 4 步,调用compareAndSet将返回 false 并将AtomicInteger保持不变,因为current与当前值不匹配AtomicInteger(由于另一个线程在第 2 步对其进行了修改);因此该方法循环并再次尝试
考虑您有三个线程 T1、T2、T3 正在运行
T1: int current = get(); == 0
T2: int current = get(); == 0
T3: int current = get(); == 0
T3: int next = current + 1;
T1: int next = current + 1;
T2: int next = current + 1;
T2: if (compareAndSet(current, next)) // true
T2: return current;
T3: if (compareAndSet(current, next)) // false
T1: if (compareAndSet(current, next)) // false
T1 和 T3 需要再试一次,第二次只有一次可能成功。
如果另一个线程正在更新,compareAndSet 可能会失败。for(;;) 有点奇怪,我会去一段时间(真)。
这称为乐观锁定。