AtomicBoolean 中 getAndSet 和 compareAndSet 的区别
Difference between getAndSet and compareAndSet in AtomicBoolean
线程标题应该是 self-explnatory...我对 AtomicBoolean
class:
中的以下方法的规范有点困惑
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);
}
}
假设我想检索当前标志值并自动更新它,这两种方法不应该产生相同的行为吗?
如果我遗漏了内部差异,我将非常感谢任何有关如何以及何时使用它们的解释。
documentation 很清楚。
getAndSet
--> "Atomically sets to the given value and returns the previous value."
compareAndSet
--> "Atomically sets the value to the given updated value if the current value == the expected value."
毫不奇怪,compareAndSet
有两个参数。
在您的具体情况下:
if (flag.getAndSet(false))
仅当其先前值为 true
时才会将 flag
设置为 false
- 这相当于
if (flag.compareAndSet(true, false))
当我检查实施时,我发现了以下内容
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
}
此外,在检查 javadoc 时,compareAndSet
仅在比较通过时才设置值,而 getAndSet
只需设置值,return 以前的值。
你可以看看代码加深理解:
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
}
在 getAndSet
中,如果布尔值在您 get()
旧值和您尝试更改其值之间发生了变化,compareAndSet
不会改变它的价值。因此,getAndSet
在循环中调用 compareAndSet
,直到布尔值设置为新值。
关于您的代码示例:
flag.getAndSet(false)
returns AtomicBoolean 的旧值。另一方面,flag.compareAndSet(x,false)
(注意有两个参数)returnsAtomicBoolean 是否被修改,或者换句话说,returnsAtomicBoolean 的旧值是否为 x。
线程有点老,但没有人提到getAndSet 会比compareAndSet 更有效率。
CAS 是一个非常昂贵的指令(在所有 CPU 架构上,因此 JVM 在这里无关紧要)。所以它们并不完全等同。
所以关于 OP,这两种方法产生相同的行为,但不会有相同的性能,尽可能使用 getAndSet。
线程标题应该是 self-explnatory...我对 AtomicBoolean
class:
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);
}
}
假设我想检索当前标志值并自动更新它,这两种方法不应该产生相同的行为吗?
如果我遗漏了内部差异,我将非常感谢任何有关如何以及何时使用它们的解释。
documentation 很清楚。
getAndSet
--> "Atomically sets to the given value and returns the previous value."compareAndSet
--> "Atomically sets the value to the given updated value if the current value == the expected value."
毫不奇怪,compareAndSet
有两个参数。
在您的具体情况下:
if (flag.getAndSet(false))
仅当其先前值为true
时才会将 - 这相当于
if (flag.compareAndSet(true, false))
flag
设置为 false
当我检查实施时,我发现了以下内容
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
}
此外,在检查 javadoc 时,compareAndSet
仅在比较通过时才设置值,而 getAndSet
只需设置值,return 以前的值。
你可以看看代码加深理解:
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
}
在 getAndSet
中,如果布尔值在您 get()
旧值和您尝试更改其值之间发生了变化,compareAndSet
不会改变它的价值。因此,getAndSet
在循环中调用 compareAndSet
,直到布尔值设置为新值。
关于您的代码示例:
flag.getAndSet(false)
returns AtomicBoolean 的旧值。另一方面,flag.compareAndSet(x,false)
(注意有两个参数)returnsAtomicBoolean 是否被修改,或者换句话说,returnsAtomicBoolean 的旧值是否为 x。
线程有点老,但没有人提到getAndSet 会比compareAndSet 更有效率。 CAS 是一个非常昂贵的指令(在所有 CPU 架构上,因此 JVM 在这里无关紧要)。所以它们并不完全等同。
所以关于 OP,这两种方法产生相同的行为,但不会有相同的性能,尽可能使用 getAndSet。