揮発性int
in Java thread-safe?つまり、ロックなしで安全に読み書きできますか?
はい、あなたはそれから読み込み、それを安全に書き込むことができます-しかし、それは読み込み/変更/書き込みサイクルであるため、安全にインクリメントするなどの複合的なことはできません。また、other変数へのアクセスと相互作用する方法の問題もあります。
Volatileの正確な性質は率直に混乱しています(詳細については、JLSの メモリモデルのセクションを参照してください )-私はpersonally通常、 AtomicInteger
を代わりに使用します。
[...]ロックなしで安全に読み書きできるように?
はい、読み取りは常に最後の書き込みの値になります(読み取りと書き込みは両方ともアトミック操作です)。
揮発性の読み取り/書き込みは、実行時にいわゆる発生前関係を導入します。
Java言語仕様 第17章:スレッドとロック
揮発性フィールド(8.3.1.4)への書き込みは、そのフィールドの以降の読み取りの前に発生します。
言い換えると、揮発性変数を処理する場合、スレッドが変数に書き込まれた最新の値を取得することを保証するために、synchronized
キーワードを使用して明示的に同期(発生前の関係を導入)する必要はありません。
Jon Skeetが指摘しているように、volatile変数の使用は制限されており、一般的にJava.util.concurrent
代わりにパッケージ。
Javaはスレッドセーフになります。アクセスと言うときは、volatile_var = 10またはint temp = volatile_var(基本的に定数値での書き込み/読み取りなど) )。Javaの揮発性キーワードにより、2つのことが保証されます。
ただし、Jon Skeetは、非アトミック操作(volatile_var = volatile + 1)では、異なるスレッドが予期しない結果を得る可能性があることを正しく述べています。
1)2つのスレッドが共有変数を読み書きしている場合、そのためにvolatileキーワードを使用するだけでは十分ではありません。その場合は、変数の読み取りと書き込みがアトミックであることを保証するために、同期を使用する必要があります。 volatile変数の読み取りまたは書き込みは、スレッドの読み取りまたは書き込みをブロックしません。これを実現するには、クリティカルセクションの周りにsynchronizedキーワードを使用する必要があります。
2)同期ブロックの代替として、Java.util.concurrentパッケージにある多くのアトミックデータ型の1つを使用することもできます。たとえば、AtomicLong、AtomicReference、または他のいずれか。
1つのライタースレッドと複数のリーダースレッドがある場合、スレッドセーフです。
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
注:ヘルパーが不変である場合、volatileキーワードは必要ありません。シングルトンは適切に動作します。
複数のスレッドによってインクリメントされているカウンターの場合(読み取り書き込み操作)は、正しい答えを与えません。この状態は、競合状態でも示されます。
public class Counter{
private volatile int i;
public int increment(){
i++;
}
}
注:ここではvolatileは役に立ちません。
Volatileが他のvolatile変数に依存していない場合、そのスレッドは読み取り操作に対して安全です。揮発性の書き込みの場合、スレッドの安全性は保証されません。
揮発性の変数iがあり、その値がjなどの別の揮発性変数に依存しているとします。スレッド1は変数jにアクセスしてインクリメントし、CPUキャッシュからメインメモリ内で変数を更新しようとしています。 Thread-2が
Thread-1の前の変数iは、メインメモリのjを実際に更新できます。 iの値は、正しくないjの古い値ごとになります。ダーティリードとも呼ばれます。
常にではない。
複数のスレッドが変数を読み書きしている場合、スレッドセーフではありません。 1つのライタースレッドと複数のリーダースレッドがある場合、スレッドセーフです。
スレッドを安全に探しているなら、 AtomicXXX クラスを使用してください
単一変数のロックフリースレッドセーフプログラミングをサポートするクラスの小さなツールキット。
本質的に、このパッケージのクラスは、揮発性の値、フィールド、および配列要素の概念を、フォームのアトミックな条件付き更新操作も提供するものに拡張します。
boolean compareAndSet(expectedValue, updateValue);
以下の投稿の@teto answerを参照してください: