2016-10-10 45 views
0

我想了解getAndIncrement中的current是如何更新的,下面是這段代碼。Java AtomicInteger getAndIncrement()和compareAndSet

public final int getAndIncrement() { 
    for (;;) { 
     int current = get(); 
     int next = current + 1; 
     if (compareAndSet(current, next)) 
      return current; 
    } 
} 

我明白compareAndSet將比較電流值是否與存儲在寄存器中的值,如果是相同的,然後更新接下來在寄存器中的值。

我不明白的是爲什麼不返回next而不是current

當進入循環時,current被設置爲一個int並且current不是一個參考值,所以如果電流被初始化爲5,那麼當它返回電流時,它是否也應該是5?或者當它返回current時,current將再次調用get()以從寄存器中獲取更新值?

+6

因爲您調用['getAndIncrement()'](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#getAndIncrement--),它有點類似於postincrement操作符('i ++')。對於你描述的行爲,有['incrementAndGet()'](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet--) ,類似於預增量運算符('++ i')。 – Turing85

+0

我所問的是「當前」如何更新爲原語,我只看到「當前」指的是更新的值? –

+0

我不完全理解你的評論。 Java是按值傳遞的,所以'current'永遠不會被改變,因此在你給出的例子中'5'將被返回。這回答了你的問題了嗎? – Turing85

回答

0

這是爲了提高併發性。

如果它返回next,該方法必須具有同步代碼,否則另一個線程可能會修改設置和返回值之間的值。

通過不返回next,只有實際的修改需要同步,把同步的責任和優化放在一個地方; compareAndSet()。當方法共享同步時,協調安全狀態更改要複雜得多。

+0

但是current不是一個引用,而是一個原始值,那麼在執行返回時,當前的調用是否再次得到()?在這裏,我只能看到當前「引用」的值被更新。 –

+0

有人可能會說,只有一個線程能夠返回一個特定的值,如果'next'沒有同步返回(並溢出asied),因爲只有一個線程能夠成功調用CAS操作並因此返回一個特定的值。 next值可能不會返回實際的當前值,但可能不需要。 – Turing85

相關問題