2016-08-06 57 views
1

下面的代碼工作沒有競爭條件爲什麼在Java中沒有競爭條件的情況下可以同時更新原子變量?

AtomicInteger atomicInt = new AtomicInteger(0); 

ExecutorService executor = Executors.newFixedThreadPool(20); 

IntStream.range(0, 1000) 
    .forEach(i -> executor.submit(atomicInt::incrementAndGet)); 

這裏是incrementAndGet

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

實現中,我們可以看到current不同步或鎖定,後一個線程獲得current另一個線程可能已經更新current

但是好像原子類避免了一些如何競爭的條件。

有人能指出我的錯誤嗎?

+0

'compareAndSet()'使用鎖定。在大多數實現中,'compareAndSet()'將執行一個特殊的指令來執行硬件鎖定(例如x86硬件上的CMPXCHG指令)。https://en.wikipedia.org/wiki/Compare-and-swap –

回答

3

compareAndSet設置值(並返回true)當且僅當第一個參數等於AtomicInteger的當前值。

也就是說,如果另一個線程已經更改了該值,那麼current將不等於當前值,並且該循環將再次運行。

documentationcompareAndSet(int expect, int update)的:

原子方式將該值設置爲給定的更新值,如果當前 值==預期值。