2012-03-21 13 views
5

このクラスはスレッドセーフですか?AtomicIntegerと同期ゲッター/セッター

一貫性のない値が表示されますか?スレッド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()が完了すると、最新の同期値が得られ、set()が完了すると、他のすべてのスレッドに更新が表示されることが保証されます。

ゲッターとセッター呼び出しのタイミングが別のスレッドで保証されることはありません。

1

@Grayが指摘したように、ここで競合状態が発生する可能性があります。

getを呼び出してからsetを呼び出す操作はアトミックではありません。 The Atomic* classesは、ロックフリーの原子条件付き更新オペレーションcompareAndSetを提供しています。スレッド安全性のためにそれを使用する必要があります。

関連する問題