2013-10-08 52 views
6

我想知道原子類中set()和compareAndSet()之間的區別。 set()方法是否也確保原子進程?例如,此代碼:Java原子變量set()vs compareAndSet()

public class sampleAtomic{ 
    private static AtomicLong id = new AtomicLong(0); 

    public void setWithSet(long newValue){ 
     id.set(newValue); 
    } 

    public void setWithCompareAndSet(long newValue){ 
     long oldVal; 
     do{ 
      oldVal = id.get(); 
     } 
     while(!id.compareAndGet(oldVal,newValue) 
    } 
} 

這兩種方法是否相同?

回答

7

setcompareAndSet方法採取不同:

  • compareAndSet:以原子方式設置的值,以給定的更新值,如果當前值等於(==)與預期值。
  • set:設置爲給定值。

set()方法是否也確保原子進程?

是。它是原子的。因爲只有一個操作涉及set新值。 set方法的源代碼如下:

public final void set(long newValue) { 
     value = newValue; 
} 
+0

感謝您的回答。我忘了檢查源代碼。你說set方法是原子的是對的,但原因並不是因爲它只有一個操作。自動類有一個名爲value的成員變量,該變量是volatile(上面set方法體中的變量),所以set方法應該是線程安全的。 –

+2

你確定'Atomic'類是原子的,因爲它們使用了volatile變量來保持它們的內部狀態。如果你定義一個易失變量volatile long value,像'value ++'這樣的操作是否是原子操作?答案是否定的。這個操作不是原子的;它實際上是三個不同的操作 - 獲取值,添加一個值,將更新後的值寫回。同時,另一個線程可以改變'value'。所以擁有volatile變量並不能保證原子性。如果一個操作/進程爲原子更新提供支持,則它是「原子」的。 –

+1

現在,'set' op是原子的,因爲它只有一個操作:'value = newValue;',即使'value'沒有定義volatile也是原子。這裏'value'被定義爲'volatile'以使用它們提供的可見性保證 - 一個線程所做的更改對其他線程始終可見。 –

-1