public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
我发现增量方法在循环块中起作用。为什么我们不能只计算一个没有任何循环的结果?它有什么意义?
如果另一个线程出现并更改了AtomicInteger
between int current = get()
and的值compareAndSet(current, next)
,则compareAndSet
调用将失败。使用循环可确保这种可能性永远不会发生。
如果compareAndSet
另一个线程增加或以其他方式AtomicInteger
在当前线程增加AtomicInteger
current = get()
AtomicInteger
next = current + 1
if(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(;;) 有点奇怪,我会去一段时间(真)。
这称为乐观锁定。