AtomicInteger中的"比较和设置"如何工作

Onk*_*nki 19 java concurrency multithreading volatile

AtomicInteger使用两个概念:CAS和volatile变量.

使用volatile变量确保当前值对所有线程可见,并且不会被缓存.

但我对CAS(比较和设置)概念感到困惑,其解释如下:

public final int getAndIncrement() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
 }
Run Code Online (Sandbox Code Playgroud)

我的问题是什么if(compareAndSet(current, next)回归false?价值会不会更新?在这种情况下,当Thread执行以下情况时会发生什么:

private AtomicInteger count = new AtomicInteger();
count.incrementAndGet();
Run Code Online (Sandbox Code Playgroud)

Old*_*eon 21

原子对象利用比较和交换机制使它们成为原子 - 即可以保证值是指定的并且现在处于新值.

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

请考虑以下情形:

  1. 线程1调用get并获取值1.
  2. 线程1计算next为2.
  3. 线程2调用get并获取值1.
  4. 线程2计算next为2.
  5. 两个线程都尝试写入值.

现在因为原子 - 只有一个线程会成功,另一个线程会false从中接收compareAndSet并再次出现.

如果没有使用这种机制,那么两个线程很可能递增该值,导致实际上只有一个增量.

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


Dra*_*vic 8

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