在 AtomicInteger.addAndGet(int) 中使用无限循环
Use of infinite loop in AtomicInteger.addAndGet(int)
在 Java 的包 java.util.concurrent.atomic AtomicInteger class 中有一个方法 addAndGet(int)
这是
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
}
这里为什么要无限循环设置一个值?
这里的动机是你最终 return next
。
意思是条件:
if (compareAndSet(current, next))
在某些迭代中将是 true
。不知道具体什么时候会发生,所以这就是为什么你需要循环直到它发生。如果您查看 compareAndSet
的代码,您会看到它 returns true
成功时,您无法知道它是否会在第一次尝试时成功:
Returns true if successful. False return indicates that the actual value was not equal to the expected value.
这是CAS loop的经典例子。 compare-and-set 是一个原子操作,它有直接的硬件支持(通常在它后面有一些 CPU 指令)。它仅在当前值等于预期值时自动更新给定变量,如果一切成功则 returns 为真。通常这个循环只执行一次。然而,在争用下(当其他线程尝试更新相同的值时),有可能在通过 get()
读取当前值和通过 compareAndSet
更新它之间另一个线程设法更新它。在这种情况下,将重试整个过程,直到成功。
这里使用无限循环只是一种风格问题。它可以使用正常的 do-while
循环重写:
public final int addAndGet(int delta) {
int current, next;
do {
current = get();
next = current + delta;
} while (!compareAndSet(current, next));
return next;
}
compareAndSet
或只是 CAS
与非阻塞线程安全算法有关。 addAndGet
情况下的增量操作是获取旧值,将其转换为新值并使用 CAS 尝试 设置新值,如果 current
不是' 在增量期间修改。如果 CAS
失败,将重试直到成功。这种策略在没有极端争用的情况下是有效的。
在 Java 的包 java.util.concurrent.atomic AtomicInteger class 中有一个方法 addAndGet(int)
这是
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
}
这里为什么要无限循环设置一个值?
这里的动机是你最终 return next
。
意思是条件:
if (compareAndSet(current, next))
在某些迭代中将是 true
。不知道具体什么时候会发生,所以这就是为什么你需要循环直到它发生。如果您查看 compareAndSet
的代码,您会看到它 returns true
成功时,您无法知道它是否会在第一次尝试时成功:
Returns true if successful. False return indicates that the actual value was not equal to the expected value.
这是CAS loop的经典例子。 compare-and-set 是一个原子操作,它有直接的硬件支持(通常在它后面有一些 CPU 指令)。它仅在当前值等于预期值时自动更新给定变量,如果一切成功则 returns 为真。通常这个循环只执行一次。然而,在争用下(当其他线程尝试更新相同的值时),有可能在通过 get()
读取当前值和通过 compareAndSet
更新它之间另一个线程设法更新它。在这种情况下,将重试整个过程,直到成功。
这里使用无限循环只是一种风格问题。它可以使用正常的 do-while
循环重写:
public final int addAndGet(int delta) {
int current, next;
do {
current = get();
next = current + delta;
} while (!compareAndSet(current, next));
return next;
}
compareAndSet
或只是 CAS
与非阻塞线程安全算法有关。 addAndGet
情况下的增量操作是获取旧值,将其转换为新值并使用 CAS 尝试 设置新值,如果 current
不是' 在增量期间修改。如果 CAS
失败,将重试直到成功。这种策略在没有极端争用的情况下是有效的。