AtomicInteger
使用两个概念:CAS和volatile
变量。
使用volatile
变量确保当前值对所有线程都可见,并且不会被缓存。
但是我对CAS(比较和设置)概念感到困惑,这个概念将在下面解释:
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
我的问题是if(compareAndSet(current, next)
返回false
的内容是什么?价值会不会更新?
在这种情况下,当Thread执行以下情况时会发生什么:
private AtomicInteger count = new AtomicInteger();
count.incrementAndGet();
答案 0 :(得分:17)
原子对象利用Compare and Swap机制使它们成为原子 - 即可以保证值 指定,现在 at新的价值。
您发布的代码会不断尝试将当前值设置为比之前更多的值。请记住,另一个线程也可以执行get
并尝试设置它。如果两个线程相互竞争以更改值,则其中一个增量可能会失败。
考虑以下情况:
get
并获取值1
。next
为2
。get
并获取值1
。next
为2
。现在因为原子 - 只有一个线程会成功,另一个会从false
收到compareAndSet
并再次转身。
如果没有使用这种机制,两个线程很可能会增加值,导致实际上只有一个增量。
令人困惑的无限循环for(;;)
只会在许多线程同时写入变量时才会真正循环。在非常重的负载下,它可能会循环几次,但它应该很快完成。
答案 1 :(得分:7)
for (;;)
是一个无限循环,所以它只会重试尝试。