AtomicBoolean中getAndSet和compareAndSet之间的区别
线程标题应该是自我探索的…我对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); } }
假设我想要检索当前标志值并自动更新它,两个方法是否应该产生相同的行为?
如果我错过了内部差异,我将非常感谢有关如何以及何时使用这些内容的任何解释。
文档很清楚。
-
getAndSet
– >“以primefaces方式设置为给定值并返回先前的值。” -
compareAndSet
– >“如果当前值==期望值,则以primefaces方式将值设置为给定的更新值。”
毫不奇怪, 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; } }
在getAndSet
,如果布尔值在get()
旧值和尝试更改其值的时间之间发生了变化, compareAndSet
将不会更改其值。 因此, getAndSet
在循环中调用compareAndSet
,直到布尔值设置为新值。
至于你的代码示例:
flag.getAndSet(false)
返回flag.getAndSet(false)
的旧值。 另一方面, flag.compareAndSet(x,false)
(注意有两个参数)返回是否修改了AtomicBoolean,换句话说,它返回AtomicBoolean的旧值是否为x。
当我检查了实现后,我发现了以下内容
public final boolean getAndSet(boolean newValue) { for (;;) { boolean current = get(); if (compareAndSet(current, newValue)) return current; } }
另外,当检查javadoc时, compareAndSet
仅在比较传递时设置值,而getAndSet
只设置值并返回先前的值。