怎么做"比较和设置"在AtomicInteger工作

时间:2015-09-17 15:27:25

标签: java multithreading concurrency volatile

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();

2 个答案:

答案 0 :(得分:17)

原子对象利用Compare and Swap机制使它们成为原子 - 即可以保证值 指定,现在 at新的价值。

您发布的代码会不断尝试将当前值设置为比之前更多的值。请记住,另一个线程也可以执行get并尝试设置它。如果两个线程相互竞争以更改值,则其中一个增量可能会失败。

考虑以下情况:

  1. 主题1调用get并获取值1
  2. 主题1计算next2
  3. 线程2调用get并获取值1
  4. 主题2计算next2
  5. 两个线程都尝试写入值。
  6. 现在因为原子 - 只有一个线程会成功,另一个会从false收到compareAndSet并再次转身。

    如果没有使用这种机制,两个线程很可能会增加值,导致实际上只有一个增量。

    令人困惑的无限循环for(;;)只会在许多线程同时写入变量时才会真正循环。在非常重的负载下,它可能会循环几次,但它应该很快完成。

答案 1 :(得分:7)

for (;;)是一个无限循环,所以它只会重试尝试。