AtomicBoolean中getAndSet和compareAndSet之间的区别

tma*_*wen 14 java synchronization atomicity atomicboolean

主题标题应该是自我探索的......我在下面的方法规范中有点困惑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);
  }
}
Run Code Online (Sandbox Code Playgroud)

假设我想要检索当前标志值并自动更新它,两个方法是否应该产生相同的行为?

如果我错过内部差异,我将非常感谢有关如何以及何时使用这些解释的任何解释.

Men*_*ena 15

文档是相当清楚的.

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

毫不奇怪,compareAndSet有两个论点.

在您的具体情况:

  • if (flag.getAndSet(false))将设置flagfalse仅当它先前的值true
  • 这相当于 if (flag.compareAndSet(true, false))

  • 是的,正如您所建议的,文档非常清楚,一般来说我可以看到差异……但我希望根据我在主线程中编写的代码片段来查看差异。它在那里有什么区别吗? (2认同)
  • “if (flag.getAndSet(false)) 仅当其先前值为 true 时才会将 flag 设置为 false” - 这是不正确的。getAndSet(<val>) 始终将值设置为 <val>,无论前一个值是 true 还是 false。 (2认同)

Era*_*ran 7

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

public final boolean getAndSet(boolean newValue) {
    for (;;) {
        boolean current = get();
        if (compareAndSet(current, newValue))
            return current;
    }
}
Run Code Online (Sandbox Code Playgroud)

getAndSet,如果布尔值get()在旧值和尝试更改其值的时间之间发生了变化,compareAndSet则不会更改其值.因此,在循环中getAndSet调用compareAndSet,直到布尔值设置为新值.

至于你的代码示例:

flag.getAndSet(false)返回AtomicBoolean的旧值.另一方面,flag.compareAndSet(x,false)(注意有两个参数)返回是否修改了AtomicBoolean,换句话说,它返回AtomicBoolean的旧值是否为x.