AtomicInteger具有两个概念:CAS和volatile变量。

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

但是我对以下解释的CAS(compare AND set)概念感到困惑:

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

我的问题是,什么if(compareAndSet(current, next)返回false?值不会更新吗?
在这种情况下,当线程执行以下情况时会发生什么:
private AtomicInteger count = new AtomicInteger();
count.incrementAndGet();

最佳答案

原子对象利用Compare and Swap机制使其具有原子性-即可以保证的值是(如指定的),现在是的新值。

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

请考虑以下情形:

  • 线程1调用get并获取值1
  • 线程1计算next2
  • 线程2调用get并获取值1
  • 线程2将next计算为2
  • 两个线程都尝试写入值。

  • 现在由于原子-,只有一个线程将继之后,另一个线程将从false接收compareAndSet并再次执行。

    如果不使用此机制,则两个线程都很有可能增加该值,从而导致实际上仅执行一次增量。

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

    关于java - AtomicInteger中的 “Compare And Set”如何工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32634280/

    10-10 22:47