仕上げのロードデータ出力の成功に別のスレッドのスレッドを待機さが、最後のプログラムがダウン実行されなかったwhileループで立ち往生されています。たとえば、今、私たちは、コードのこの部分を持っています。
パブリック クラスVolatileDemo {
プライベート 静的 ブールフラグ= 偽;
// プライベート静的揮発性ブールフラグ= falseは、
パブリック 静的 ボイド(文字列[]引数)主は、スロー例外{
新しいスレッドを(() - > {
するSystem.out.println( "等待装载数据..." );
ながら(!フラグ){
}
のSystem.out.println ( "====== SUCCESS =====" );
})(開始)。
Thread.sleep( 2000 );
新しいスレッド(() - > {
するSystem.out.println( "ローディング開始" )
でフラグ = trueに、
のSystem.out.println( "完成ローディング" );
})スタート();.
}
}
/ * コンソール出力
待機データをロードします。。。。
スタートのロード
完成読み込み
* /
この問題の原因は、JMMアトミック操作によって引き起こされます。JMMメモリモデルは、Javaスレッドのメモリモデルを言って正確なJavaのメモリモデル、です。また、CPUのキャッシュモデルタイプ、CPUのキャッシュモデルは確立に基づいています。
JMM 8つのアトミック操作の全リード(READ):メインメモリからのリードデータ ロード(負荷):ワーキングメモリは、メモリデータ読み出しする ワーキングメモリ計算におけるデータ取得:利用(使用)を 割り当て(アサイン)を:ワーキングメモリに計算された値を再割り当てする 店舗(店舗):ワーキングメモリデータがメインメモリに書き込まれる メインメモリ内の変数に割り当てられた格納最後の変数値:ライト(書き込み) ロック(ロック):メインメモリは、スレッド排他状態として識別、変数をロック 、アンロック(ロック解除):この変数は、メインメモリ変数のロックを解除し、他のスレッドは、ロック解除をロックすることができ
私たちは、そのスレッド1が変数のコピーがワーキングメモリにロードされており、メインメモリ2に格納された値は、スレッドの後に計算されます後、しかし、スレッド1を指示する方法はありませんので、スレッド安全性の問題があった見ることができます。実際には、メインメモリとCPUの相互作用は、このようなコンセプト「バス」を通過します、このCPUのデータの不整合を解決するために2つのオプションがあります。
バスロック(低パフォーマンス)が
初期のCPUバスがロックされ、データは生きてロックし、そう他のスレッドは、スレッドは、このデータロック解除後に実行されることを他のスレッドまで動作可能にするためには、それに読み取りまたは書き込みができません。読み取り、書き込みが終了するまで開始された後にのみロックを解除すること。
MESIキャッシュ・コヒーレンシー・プロトコル
それぞれのバッファに同じデータを読み取るためのポスト、複数のスレッドの後、CPUは、キャッシュされたデータを変更するアセンブリ言語で実装されてメインメモリに即座に同期されます。CPUは、キャッシュデータがのでメインメモリの値を読みに行く無効化される所有するデータを変更する(リスナーとして理解することができる)他のバススヌーピング機構によって知覚することができます。だから、MESI契約は、小さく、短いロックの粒度をロックストアで開始することです。実際には、可視性を実現するように揮発性です。この中間プロセスと店舗と書き込みに、だけでなく、他のCPUのキャッシュデータのブランキングにいくつかの手順は、時間がかかることがありますされているので、彼は非アトミック操作であるので、このプロセスは、他の人がデータを変更することがあります。