Java Multi-Threadedプログラミングでは、揮発性がよく見られます。このキーワードは、多くの場合、同期またはロックと混同されることがよくあります。特定の分析は次のとおりです。
マルチスレッド環境では、メンバー変数の可視性の問題があります。Javaの各スレッドには、スレッドスタックのメモリスペースがあり、実行中にスレッドの変数情報を保存します。スレッドが特定の変数値にアクセスすると、最初に変数のアドレスに基づいてオブジェクトのヒープメモリまたはスタックの特定のコンテンツ(ネイティブデータ型)が見つかり、次にこのスレッドのスレッドスタックに同じ値コピーを保存します。次に、この変数のすべての操作は、スレッドが終了する前にスタック内の変数コンテンツとは何の関係もありません。スレッドスタックのコピーで動作します。操作が完了した後、操作の結果はメインメモリに書き戻されます。 2つのスレッドAとBがあり、同僚が特定の変数Xを操作する場合。 aはxに1を追加し、bで取得したコピーはx plus 1またはxの結果である可能性があります。揮発性キーワードを追加するためにメモリ内の最新のデータ変数が必要であることを確認するために、xで動作するたびに、スレッドスタック内の変数の値がメモリ内の変数の値と同じであるかどうかを確認します。
例えば:
パブリッククラスのスレッドシー{// T1スレッドはフラグの値に基づいて対応する操作を実行し、メインスレッドはT1 public static void main(string [] args)の値を変更します。スレッドT1 =新しいスレッド(th); t1.start(); thread.sleep(1000); th.ChangeFlag(); Thread.Sleep(2000); system.out.println(th.getflag()); }} classスレッドテストはrunnable {//スレッドが変数にアクセスすると、対応するスレッドスタックにロードします。各操作では、メモリプライベートの揮発性ブールストップフラグの最新データを取得する必要があります。 @Override public void run(){int i = 0; while(!stopflag){i ++; system.out.println( "=="+thread.currentThread()。getName()); } system.out.println( "スレッド仕上げ:"+i); } public void changeflag(){this.stopflag = true; system.out.println(thread.currentthread()。getname()+"*********"); } public boolean getflag(){return stopflag; }}上記のコードが削除された場合、デッドループで実行され続けます。
しかし、揮発性はスレッドセーフの同期を保証することはできません
例えば:
public class Sthreadsave実装runnable {static threadsave sync = new threadsave();静的揮発性int j = 0; // lock lock = new ReentrantLock(); public void inscane(){// lock.lock(); for(int i = 0; i <10000000; i ++){j ++; } // lock.unlock(); } @Override public void run(){inscane(); } public static void main(string [] args)throws arturtedexception {thread t1 = newスレッド(同期);スレッドT2 =新しいスレッド(同期); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(j); }}上記のコードによる実行の結果は20000000であるとは予想されていません、
揮発性によって変更された変数の場合、JVM仮想マシンは、メインメモリからスレッドワーキングメモリにロードされた値が最新であることのみを保証するためです。
たとえば、スレッド1とスレッド2がスレッドスタックとメインメモリの読み取りおよびロード操作を実行し、メインメモリのカウント値が5であることがわかった場合、最新の値はロードされます。スレッド1ヒープカウントが変更された後、メインメモリに書き込まれ、メインメモリのカウント変数は6になります。
スレッド2はすでに読み取り操作とロード操作を実行しているため、操作を実行した後、メインメモリカウントの変数値も6に更新されます。
これにより、2つのスレッドが時間内に揮発性キーワードで変更された後、同時性が発生します。
要約すれば:
揮発性は、スレッドが現在のスレッドスタックの変動値がメインメモリのデータ値と同じかどうかをチェックするアクションを実行することを保証します。ロックまたは同期すると、特定の瞬間に単一のスレッドのみがメソッドに入ることを保証し、それによりスレッドの安全性が保証されます。
したがって、複数のスレッドが揮発性変数を変更する場合、実際の論理的な意味はありません。スレッドが変更に依存する他のスレッドの変数値を変更すると、現時点では役立ちます。
上記はこの記事に関するものです。すべての人の学習に役立つことを願っています。