ドキュメントから:
揮発性変数を使用すると、メモリの一貫性エラーのリスクが軽減されます
しかし、これは volatile 変数が正しく動作しないことがあることを意味しますか? それがどのように使用できるかが奇妙です-私の意見では、時々機能することもあれば機能しないこともある非常に悪いコードです。Google にアクセスしようとしましたが、揮発性のメモリ一貫性エラーの例が見つかりませんでした。提案していただけますか?
ドキュメントから:
揮発性変数を使用すると、メモリの一貫性エラーのリスクが軽減されます
しかし、これは volatile 変数が正しく動作しないことがあることを意味しますか? それがどのように使用できるかが奇妙です-私の意見では、時々機能することもあれば機能しないこともある非常に悪いコードです。Google にアクセスしようとしましたが、揮発性のメモリ一貫性エラーの例が見つかりませんでした。提案していただけますか?
問題は、volatile
動作が信頼できないということではありません。それは常に機能するはずの方法で機能します。問題は、それが機能するはずの方法が、同時実行制御には適切でない場合があることです。volatile
間違った状況で使用すると、メモリの一貫性エラーが発生する可能性があります。
volatile
変数には常に、すべてのスレッドに伝達される書き込みがあります。ただし、さまざまなスレッド間で変数をインクリメントする必要があるとします。これを行う(*):
volatile int mCounter;
// later, in some code that might be executed simultaneously on multiple threads:
mCounter++;
カウンターの増分が失われる可能性があります。これはmCounter
、新しい値を書き込む前に、各スレッドが最初に の値を読み取る必要があるためです。これら 2 つのステップの間に、別のスレッドが の値を変更した可能性がありますmCounter
。このような状況では、データの整合性を確保するsynchronized
のではなく、ブロックに依存する必要があります。volatile
volatile
vs.の詳細については、Brian Goetzsynchronized
の記事Managing volatilityをお勧めします。
(*)AtomicInteger
上記は;で実装したほうがよいと思います。これは、要点を説明するための不自然な例です。
揮発性は次のことを行います。
-スレッド内の値のキャッシュを防ぎます。
-オブジェクトのフィールドの値のコピーを持つスレッドが、メモリ内に存在するメイン コピーと一致することを確認します。
-データがメモリに直接書き込まれ、メモリ自体から読み取られることを確認します。
## しかし、volatile が失敗する条件:
-を作るNon-Atomic statement Volatile
。
例えば:
int count = 0;
count++; // Increment operator is Not Atomic in java
## より良いオプション:
1.常に以下に従うことをお勧めしますBrian's Rule
。
When ever we write a variable which is next to be read by another thread, or when we are reading a variable which is written just by another thread, it needs to be synchronized.
The shared fields must be made private, making the read and write methods/atomic statements synchronized.
2. 2番目のオプションは、AtomicInteger、AtomicLong、AtomicReference などAtomic Classes
のを使用しています。
## このリンクを参照してください。私はあなたと同じような質問をしました: