2014-10-05 72 views
0

有人可以解釋爲無窮大循環的目的....這是官方Java的AtomicBoolean getAndSet方法的定義什麼在下面的代碼

public final boolean getAndSet(boolean newValue) { 
     for (;;) { 
      boolean current = get(); 
      if (compareAndSet(current, newValue)) 
       return current; 
     } 
    } 

回答

2

在Java 8中,sourcecode已略有調整,使其更容易理解:

public final boolean getAndSet(boolean newValue) { 
    boolean prev; 
    do { 
     prev = get(); 
    } while (!compareAndSet(prev, newValue)); 
    return prev; 
} 

正如你所看到的,compareAndSet,它返回一個布爾值,它來自本地函數Unsafe.compareAndSwapInt,可能會失敗。在這種情況下,操作只需重複一次。

Unsafe.compareAndSwapInt文件,

 
Atomically update Java variable to x if it is currently holding expected. 
Returns: 
    true if successful 

如果AtomicBoolean的價值一直呼籲get()Unsafe.compareAndSwapInt一些點之間變化的函數將失敗。這通常不應該是這種情況,但是當它發生時,它會再次查詢當前值,並希望同樣的事情不會重複。

+0

謝謝你的回答。如果以某種方式c​​ompareAndSet不寫入true和prev和newValue(因爲它的計數器或其值不重複)將永遠不會匹配。是否有使用for循環的特定原因?不應該有一些例外引發或其他退出策略? – 2014-10-08 12:28:28

+0

@ bharat9848:我不這麼認爲,因爲compareAndSet可能失敗的最常見情況是數據競爭,在這種情況下,它有可能在下一次迭代中工作。所以,爲了簡化調用方,最好不要拋出異常。即使它會拋出一個,你會怎麼做?顯示它?重試操作? – tilpner 2014-10-08 12:33:18

1

顯然,這不是一個無限循環。環路只是有身體內部的退出條件:

return current; 

在一般情況下,這是樂觀的,無鎖的原子操作使用的典型成語。比較和交換(CAS)操作將重試直到它成功,並且一旦它不從另一個線程競爭,它就會成功。更確切地說,只要get()的返回值與compareAndSet()觀察到的當前值相匹配,就會滿足退出條件。很難而不是來滿足這個條件,而且很少發生。

+0

感謝您的回答。如果以某種方式c​​ompareAndSet不寫入true和prev和newValue(因爲它的計數器或其值不重複)將永遠不會匹配。是否有使用for循環的特定原因?不應該有一些例外引發或其他退出策略? – 2014-10-08 12:29:42

+0

不,重試正是所有無鎖原子操作的預期策略。 – 2014-10-08 14:55:14

相關問題