简体   繁体   English

AtomicBoolean 中 getAndSet 和 compareAndSet 的区别

[英]Difference between getAndSet and compareAndSet in AtomicBoolean

The thread title should be self-explnatory... I'm a bit confused between the specification of below methos from AtomicBoolean class:线程标题应该是不言自明的......我对AtomicBoolean类的以下方法的规范有点困惑:

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

My assemption is that both would result in the same behavior when used as a boolean clause in an if condition:我的看法是,当在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);
  }
}

Assuming that I want to retrieve the current flag value and update it automaticlly, shouldn't both methods produce the same behavior?假设我想检索当前标志值并自动更新它,这两种方法不应该产生相同的行为吗?

I would much appreciate any explanations regarding how and when to use each of those if I'm missing internal differences.如果我缺少内部差异,我将非常感谢有关如何以及何时使用其中每一个的任何解释。

The documentation is pretty clear. 文档很清楚。

  • getAndSet --> "Atomically sets to the given value and returns the previous value." getAndSet --> "原子地设置为给定值并返回前一个值。"
  • compareAndSet --> "Atomically sets the value to the given updated value if the current value == the expected value." compareAndSet --> “如果当前值 == 预期值,则自动将值设置为给定的更新值。”

Not surprisingly, compareAndSet takes two arguments.毫不奇怪, compareAndSet有两个参数。

In your specific case:在您的具体情况下:

  • if (flag.getAndSet(false)) will set flag to false only if its previous value was true if (flag.getAndSet(false))仅当其先前的值为true时才会将flag设置为false
  • That would be the equivalent of if (flag.compareAndSet(true, false))这相当于if (flag.compareAndSet(true, false))

You can look at the code for better understanding :您可以查看代码以更好地理解:

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

In getAndSet , if the value of the boolean has changed between the time you get() the old value and the time you try to change its value, compareAndSet won't change its value.getAndSet ,如果布尔值在您get()旧值和您尝试更改其值的时间之间发生了变化, compareAndSet不会更改其值。 Therefore, getAndSet calls compareAndSet in a loop until the boolean is set to the new value.因此, getAndSet在循环中调用compareAndSet ,直到布尔值设置为新值。

As to your code example :至于你的代码示例:

flag.getAndSet(false) returns the old value of the AtomicBoolean. flag.getAndSet(false)返回flag.getAndSet(false)的旧值。 On the other hand, flag.compareAndSet(x,false) (note there are two arguments) returns whether the AtomicBoolean was modified, or in other words, it returns whether the old value of the AtomicBoolean was x.另一方面, flag.compareAndSet(x,false) (注意有两个参数)返回AtomicBoolean 是否被修改,或者换句话说,它返回AtomicBoolean 的旧值是否为x。

When I have checked the implementation I found following当我检查了实现时,我发现了以下内容

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

Also when checking the javadoc, compareAndSet sets value only if the comparison pass while getAndSet simply set the value and return the previous value.同样在检查 javadoc 时, compareAndSet仅在比较通过getAndSet设置值,而getAndSet仅设置值并返回前一个值。

The thread is a bit old but nobody mentioned that getAndSet will be more efficient than compareAndSet.该线程有点旧,但没有人提到 getAndSet 将比 compareAndSet 更有效。 CAS is a very costly instruction (on all CPU architectures, so JVM does not matter here). CAS 是一条非常昂贵的指令(在所有 CPU 架构上,因此 JVM 在这里无关紧要)。 So they are not really equivalent.所以它们并不是真正等效的。

So regarding the OP, both methods produce the same behaviour but it will not have the same performance, use getAndSet when you can.因此,关于 OP,这两种方法产生相同的行为,但不会具有相同的性能,请尽可能使用 getAndSet。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AtomicBoolean.set(flag) 和 AtomicBoolean.compareAndSet(,flag? flag) 有什么区别? - What is the difference between AtomicBoolean.set(flag) and AtomicBoolean.compareAndSet(!flag, flag)? Java 中原子 set() 和 getAndSet() 方法的区别 - Difference between Atomic set() and getAndSet() methods in Java AtomicBoolean中的compareAndSet方法有问题吗? - Any issue with compareAndSet method in AtomicBoolean? CompareAndSet和IncrementAndGet之间的真正区别是什么? - What is the true difference between CompareAndSet and IncrementAndGet? AtomicReference 中的 compareAndSet 和 weakCompareAndSet 有什么区别? - what's the difference between compareAndSet and weakCompareAndSet in AtomicReference? 对来自异步线程的信号使用静态布尔值与AtomicBoolean的区别 - Difference between using static boolean vs AtomicBoolean for signals from asyn threads AtomicBoolean与同步块有什么区别 - AtomicBoolean vs Synchronized block, whats the difference 在AtomicBoolean上同步? - Synchronizing on AtomicBoolean? Java:锁定线程时,AtomicBoolean和静态布尔变量之间有什么不同? - Java: What is the different between AtomicBoolean and a static boolean variable when locking a thread? 如何正确使用 AtomicInteger getAndSet? - How to use AtomicInteger getAndSet correctly?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM