有人可以解釋爲無窮大循環的目的....這是官方Java的AtomicBoolean getAndSet方法的定義什麼在下面的代碼
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
}
有人可以解釋爲無窮大循環的目的....這是官方Java的AtomicBoolean getAndSet方法的定義什麼在下面的代碼
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
}
在Java 8中,sourcecode已略有調整,使其更容易理解:
public final boolean getAndSet(boolean newValue) {
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
正如你所看到的,compareAndSet,它返回一個布爾值,它來自本地函數Unsafe.compareAndSwapInt,可能會失敗。在這種情況下,操作只需重複一次。
Atomically update Java variable to x if it is currently holding expected. Returns: true if successful
如果AtomicBoolean
的價值一直呼籲get()
和Unsafe.compareAndSwapInt一些點之間變化的函數將失敗。這通常不應該是這種情況,但是當它發生時,它會再次查詢當前值,並希望同樣的事情不會重複。
顯然,這不是一個無限循環。環路只是有身體內部的退出條件:
return current;
在一般情況下,這是樂觀的,無鎖的原子操作使用的典型成語。比較和交換(CAS)操作將重試直到它成功,並且一旦它不從另一個線程競爭,它就會成功。更確切地說,只要get()
的返回值與compareAndSet()
觀察到的當前值相匹配,就會滿足退出條件。很難而不是來滿足這個條件,而且很少發生。
感謝您的回答。如果以某種方式compareAndSet不寫入true和prev和newValue(因爲它的計數器或其值不重複)將永遠不會匹配。是否有使用for循環的特定原因?不應該有一些例外引發或其他退出策略? – 2014-10-08 12:29:42
不,重試正是所有無鎖原子操作的預期策略。 – 2014-10-08 14:55:14
謝謝你的回答。如果以某種方式compareAndSet不寫入true和prev和newValue(因爲它的計數器或其值不重複)將永遠不會匹配。是否有使用for循環的特定原因?不應該有一些例外引發或其他退出策略? – 2014-10-08 12:28:28
@ bharat9848:我不這麼認爲,因爲compareAndSet可能失敗的最常見情況是數據競爭,在這種情況下,它有可能在下一次迭代中工作。所以,爲了簡化調用方,最好不要拋出異常。即使它會拋出一個,你會怎麼做?顯示它?重試操作? – tilpner 2014-10-08 12:33:18