在Java的包中java.util.concurrent.atomic AtomicInteger类有一个方法addAndGet(int)
是
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
}
为什么它在这里使用无限循环来设置值?
答案 0 :(得分:5)
这是CAS loop的经典示例。比较和设置是一个原子操作,它具有直接的硬件支持(通常它背后有一些CPU指令)。它仅在当前值等于预期值时原子地更新给定变量,并且如果一切都成功则返回true。通常这个循环只执行一次。但是在竞争中(当其他线程尝试更新相同的值时),可能在通过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;
}
答案 1 :(得分:2)
compareAndSet
或仅CAS
与非阻塞线程安全算法有关。在addAndGet
的情况下,增量操作是获取旧值,将其转换为新值并使用CAS 尝试设置新值,如果current
不是&#39}。在增量期间修改。如果CAS
失败,则会重试,直到成功为止。在没有极端争用的情况下,这种策略是有效的。
答案 2 :(得分:0)
这里的动机是最终 TEST
。
意思是条件:
return next
在某次迭代中会if (compareAndSet(current, next))
。目前还不知道它究竟会发生什么,所以这就是你需要循环直到它的原因。如果您查看compareAndSet
的代码,您会看到它在成功时返回true
,并且您无法在第一次尝试时知道它会成功:
如果成功则返回true。错误返回表示实际值不等于预期值。