2012-03-21 73 views
5

這個類是線程安全的嗎?AtomicInteger vs synchronized getters/setters

是否有可能看到不一致的值?可以說最初a的值是80.線程1調用setA(100)並進入函數但尚未調用a.set(100),線程2併發調用getA()。線程2可以看到80嗎?

public class A { 
    private AtomicInteger a; 

    public int getA() { 
     return a.get() 
    } 

    public void setA(int newVal){ 
     a.set(newVal); 
    } 
} 

我知道同步它將保證線程2看到100,但不確定與AtomicInteger。

回答

9

這個類是線程安全的嗎?

是的。

線程1調用setA(100)並進入函數但尚未調用a.set(100),線程2同時調用getA()。線程2可以看到80嗎?

是的。直到與AtomicInteger內部的易失性字段同步的內存屏蔽代碼完成,競爭條件可以顯示80或100.

線程1甚至可以輸入AtomicInteger.set方法,並位於內部字段賦值之前,仍然可以返回80通過獲得AtomicInteger.get方法。

關於的值不會被其他線程更新。什麼是保證是當get()完成,你得到最新的同步值,當完成時,所有其他線程將看到更新。

無法保證時間 getter和setter調用在不同的線程。

1

正如@格雷指出的那樣,這裏有可能出現競賽狀況。

調用get然後set不是原子操作。 The Atomic* classes提供無鎖原子條件更新操作compareAndSet - 您應該使用該操作來保證線程安全。