getAndSet 和 compareAndSet 在 AtomicBoolean 中的区别

线程标题应为自解释性...我对类中以下methos的规范有点困惑:AtomicBoolean

  • java.util.concurrent.atomic.AtomicBoolean#compareAndSet
  • java.util.concurrent.atomic.AtomicBoolean#getAndSet

我的解释是,当在条件中用作布尔子句时,两者都会导致相同的行为:if

public class Test {
  private AtomicBoolean flag = AtomicBoolean(false);

  public void processSomeAction() {
    if (flag.getAndSet(false)) { // Shouldn't this be similar to flag.compareAndSet(false)
      // process some action
    }
  }
  //...
  private void internalMutatorMethod() {
    // do some staff then update the atomic flag
    flas.set(true);
  }
}

假设我想检索当前标志值并自动更新它,这两种方法不应该产生相同的行为吗?

如果我错过了内部差异,我将不胜感激关于如何以及何时使用它们的任何解释。


答案 1

文档非常清楚。

  • getAndSet--> “原子设置为给定值并返回前一个值”。
  • compareAndSet--> “如果当前值 == 预期值,则以原子方式将值设置为给定的更新值。

毫不奇怪,需要两个论点。compareAndSet

在您的特定情况下:

  • if (flag.getAndSet(false))将设置为仅当其以前的值为flagfalsetrue
  • 这相当于if (flag.compareAndSet(true, false))

答案 2

您可以查看代码以更好地理解:

public final boolean getAndSet(boolean newValue) {
    for (;;) {
        boolean current = get();
        if (compareAndSet(current, newValue))
            return current;
    }
}

在 中,如果布尔值的值在旧值和尝试更改其值的时间之间已更改,则不会更改其值。因此,在循环中调用,直到布尔值设置为新值。getAndSetget()compareAndSetgetAndSetcompareAndSet

至于你的代码示例:

flag.getAndSet(false)返回原子布尔值的旧值。另一方面,(注意有两个参数)返回原子布尔值是否被修改,或者换句话说,它返回原子布尔的旧值是否为x。flag.compareAndSet(x,false)


推荐