volatileキーワード、最初のトークJavaの再配置命令実行順序コードを説明する前に。
指示を並べ替えます:
公共ボイド和(){ int型のx = 1。 int型、Y = 2。
INT X = X + 1。
INT合計= X + Y。 }
最終的な加算;ギブギブ割り当てX Yの割当てを実行したときに注文コードは、次いで、X = X + 1を実行します。
X = X + 1と加算命令再配置を記述されていない= X + Yが、X = 1、Y = 2が相互に排他的ではないので、直接割り当てた後に(パフォーマンスの考慮のために最適化されたX X xは、メモリアドレスを再取得動作時間)を節約することができ、命令が再び最大Y-X割り当て割り当てに再配置することができます。
転位命令は、最適化手法の結果には影響しません。
シーケンシャルコード実行:前とシングルスレッドコードコンパイラの最適化後の揮発性変数が再配置されていない場合は、実行コード・シーケンス。共有変数への同時実行、マルチスレッド、一連の動作。競争がマルチスレッド実行であるため、実行順序はランダムです、揮発性の変数を操作しながら、アトミック操作変数を壊す可能性があります。
アトミック操作変数を保証するものではありませ1.volatlie
int型変数の基本データ型:ヒープメモリ内のマルチスレッド動作変数の値にスレッドスタックから読み出され、変数の値、変数値をヒープメモリに書き戻され、スレッド・スタック上で動作します。原子を破壊すると、2つのスレッドが、変数及び予測不能の値を引き起こし、中断されたデータを読み取るためにバックヒープメモリヒープメモリの処理の途中に書かれていることをいいます。例えば:X = 1を削除し、X ++最初の操作、第二のスレッドx--操作スレッド、最終結果が行われる可能性があることも、2 0であってもよいです。
パブリッククラスVolatileNotAtomic { プライベート静的揮発性の長い数= 0L; プライベート静的最終int型のNUMBER = 10000; パブリック静的無効メイン(文字列[] args){ スレッドsubstractThread =新しいSubstractThread()。 substractThread.start(); {ため(; iは番号を<I ++は、I = 0 INT) //synchronized(VolatileNotAtomic.classが){ ++数えます。 //} } //等待线程结束 一方(substractThread.isAlive()){} のSystem.out.println( "カウント" +カウント)。 } プライベート静的クラスSubstractThreadは、Thread {拡張 @Override ます。public void実行(){ ための式(I = 0 int型、私は数<; Iは++){ // {(VolatileNotAtomic.class)同期 count--を。 //} } } } }
このコードを実行し、結果が0ではない、揮発性変数は、操作がアトミックではない説明しました。同期コードブロックのコメントにオープンアトミック操作を、確認してください。
視認性の命令のみ再配置が発生しないことを確認するために揮発性メモリのセマンティクス、変数が保証されています。ここで、メモリは、代わりに、ワーキングメモリ(スタックメモリ)のメインメモリ(ヒープメモリ)のことをいいます。スレッドをバック読み書き、ワーキングメモリにロードされ、メインメモリの読み込みを開始共有変数のスレッドの値を取得する変数の値がワーキングメモリ内で発生しており、メインメモリマルチスレッドでは、この時間を同期の値を保証するものではありません。とき、変数の値が矛盾につながります。volitale後にメインメモリ値の視認性を確保するために、メインメモリから読み出された可変力可変値で修飾されました。
2.揮発性変数自体、書き込みのアトミック性を確保するため、書き込み動作後に読み出し動作を、一般的なアプリケーション・シナリオ:追記多くを読みます
マルチ揮発性の読み書きアプリケーションを定めるために、単一のケースダブルロックの目的を達成するための分析は、次の手順。
オブジェクトのシーケンスの例:
親静的メンバと静的コードブロック==>親クラス静的メソッド==>サブ静的メンバと静的コードブロック==>サブクラス静的メソッド==>通常のメンバーと親クラス==> =親クラスのコンストラクタ=>サブクラスのメンバーと通常の方法==>サブクラスのコンストラクタ
まず、オブジェクトは、ヒープメモリ空間を適用し、インスタンス化時にインスタンス化プロセスを実行します。
次のように二重の単一のロックは、被写体を実施例:
パブリッククラスシングルトン{ プライベート静的シングルトンシングルトン= NULL; パブリック静的シングルトンのgetInstance(){ {IF(ヌル==シングルトン) 同期(Singleton.class){ IF(ヌル==シングルトン){ シングルトン=新しいシングルトン()。 } } } 戻りシングルトン。 } }
上記のコードという問題:複数の実行スレッド、スレッド1は新しいシングルトン()を実行するが、オブジェクトのインスタンス化プロセスが完了していない場合は、スレッド2が取得されるコールgetInsatnce未完成のインスタンス化されたオブジェクトは、(オブジェクトが割り当てられメモリにアクセスすることができる)、間違った結果をもたらします。
ただsinleton変数を加えた揮発性のキーワードの前に問題を解決します。
パブリッククラスシングルトン{ プライベート静的揮発性のシングルトンシングルトン= NULL; パブリック静的シングルトンのgetInstance(){ {IF(ヌル==シングルトン) 同期(Singleton.class){ IF(ヌル==シングルトン){ シングルトン=新しいシングルトン()。 } } } 戻りシングルトン。 } }