給定一個AtomicLong物件,將值減少 delta 的正確方法是什么?
選項1
AtomicLong count = new AtomicLong(0L);
public void decrementCount(long decrementBy) {
count.getAndUpdate(l->count.get() - decrementBy);
}
選項 2
AtomicLong count = new AtomicLong(0L);
public void decrementCount(long decrementBy) {
count.getAndAdd(-decrementBy);
}
雖然兩者都給出了所需的結果,但我想了解在什么情況下它們不會代表所需的行為,即原子地減少 long 值?(例如,第二種方法的一個缺點可能是負號導致一些位溢位,但我不確定這是否屬實)
uj5u.com熱心網友回復:
count.getAndUpdate(l->count.get() - decrementBy);
這不能以原子方式作業。getAndUpdate大致是這樣作業的:
long getAndUpdate(LongUnaryOperator op) {
long current;
long newValue;
do {
current = this.get();
newValue = op.apply(current);
while (!compareAndSet(current, newValue));
return current;
}
通過count.get()在 lambda 內部重新讀取,您正在讀取AtomicLong then的值current,如果其他執行緒更新了AtomicLong其間的值,則該值可能與傳遞的值不同;然后您會根據更新后的值進行更新,而不是current.
使用您傳入的值l:
count.getAndUpdate(l->l - decrementBy);
但getAndAdd(-decrementBy)更容易。
uj5u.com熱心網友回復:
您的第二種方法是正確的,如getAndAdd):
以原子方式將給定值與當前值相加
AtomicLong count = new AtomicLong(0L);
count.getAndAdd(-decrementBy);
您的第一種方法略有偏差,因為它使用count.get(), when "The function should be side-effect-free",并且LongUnaryOperatorie 理想情況下僅使用它作為引數給出的 Long-value。雖然讀取原子值可能不會嚴格計為副作用,但沒有必要且不必要地使更新非原子化。
uj5u.com熱心網友回復:
我認為這個類已經準備好了所有方法:
AtomicLong 類為您提供了一個可以原子讀寫的 long 變數,其中還包含高級原子操作
取決于您要在更新之前和之后使用的順序或先更新后閱讀。你有增加和減少的 arpopiate 方法:
addAndGet()
getAndAdd()
getAndIncrement()
incrementAndGet()
getAndDecrement()
decrementAndGet()
然后是這樣的:
AtomicLong atomicLong = new AtomicLong(22);
System.out.println(atomicLong.getAndAdd(-1));
System.out.println(atomicLong.addAndGet(-1));
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/316286.html
