0
public final int getAndIncrement() {
for (;;) {
    int current = get();
    int next = current + 1;
    if (compareAndSet(current, next))
        return current;
   }
}

我发现增量方法在循环块中起作用。为什么我们不能只计算一个没有任何循环的结果?它有什么意义?

4

4 回答 4

6

如果另一个线程出现并更改了AtomicIntegerbetween int current = get()and的值compareAndSet(current, next),则compareAndSet调用将失败。使用循环可确保这种可能性永远不会发生。

于 2013-07-18T19:30:59.853 回答
6

如果compareAndSet另一个线程增加或以其他方式AtomicInteger在当前线程增加AtomicInteger

  1. 当前线程调用current = get()
  2. 另一个线程修改AtomicInteger
  3. 当前线程调用next = current + 1
  4. 当前线程调用if(compareAndSet(current, next))

在第 4 步,调用compareAndSet将返回 false 并将AtomicInteger保持不变,因为current与当前值不匹配AtomicInteger(由于另一个线程在第 2 步对其进行了修改);因此该方法循环并再次尝试

于 2013-07-18T19:31:51.707 回答
1

考虑您有三个线程 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 需要再试一次,第二次只有一次可能成功。

于 2013-07-18T19:44:07.253 回答
1

如果另一个线程正在更新,compareAndSet 可能会失败。for(;;) 有点奇怪,我会去一段时间(真)。

这称为乐观锁定。

于 2013-07-18T19:32:28.563 回答