![](/img/trans.png)
[英]What is the difference between AtomicBoolean.set(flag) and AtomicBoolean.compareAndSet(!flag, flag)?
[英]Difference between getAndSet and compareAndSet in 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);
}
}
假設我想檢索當前標志值並自動更新它,這兩種方法不應該產生相同的行為嗎?
如果我缺少內部差異,我將非常感謝有關如何以及何時使用其中每一個的任何解釋。
文檔很清楚。
getAndSet
--> "原子地設置為給定值並返回前一個值。"compareAndSet
--> “如果當前值 == 預期值,則自動將值設置為給定的更新值。” 毫不奇怪, 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
設置值,而getAndSet
僅設置值並返回前一個值。
該線程有點舊,但沒有人提到 getAndSet 將比 compareAndSet 更有效。 CAS 是一條非常昂貴的指令(在所有 CPU 架構上,因此 JVM 在這里無關緊要)。 所以它們並不是真正等效的。
因此,關於 OP,這兩種方法產生相同的行為,但不會具有相同的性能,請盡可能使用 getAndSet。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.