JAva volatile進級(一)

5263 ワード

この文章はvolatileを勉強し続けます.前の文章 volatileとsynchonizedを簡単に紹介しましたが、この文章ではいつvolatileが使えるかを説明します.
まずコードを見てください.
package com.chzhao.voltiletest;



public class ChangeValue extends Thread {



    public void run() {

        try {

            Thread.sleep(2000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        GlobalValues.STATUS = "stop";

    }

}
package com.chzhao.voltiletest;



public class VolatileDeep extends Thread {



    public void run() {

        while (true) {

            try {

                Thread.sleep(1);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            if (GlobalValues.STATUS.equals("stop")) {

                System.out.println(this.getName() + "stop");

                GlobalValues.STATUS = "running";

            }

        }

    }



    public static void main(String[] args) {

        Thread t1 = new VolatileDeep();

        t1.setName("t1");

        t1.start();



        Thread t2 = new VolatileDeep();

        t2.setName("t2");

        t2.start();



        Thread t3 = new ChangeValue();

        t3.start();

    }

}
package com.chzhao.voltiletest;



public class GlobalValues {

    public static String STATUS = "running";

}

このコードは簡単ですが、出力は何ですか?
出力はt 1 stop?
それともt 2 stop?
やはり
t1stopt2stop
?
真実は以上の3つが可能です.
変数STATUSはスレッドが安全ではないので、1つの状態表示としてマルチスレッドの場合は状態がわかりません.
ただし、変数の前にvolatileキーを付けると.
package com.chzhao.voltiletest;



public class GlobalValues {

    public volatile static String STATUS = "running";

}

毎回出力されます
t1stopt2stop
もちろん、順番は決まっていません.
 
これは,volatileキーワードが付加されている場合,識別状態としてスレッドの安全を保証できることを示している.どうしてですか.
『Java理論と実践:Volatile変数を正しく使用する』で紹介されています.
Volatile      synchronized       ,         。             volatile       。Volatile            ,                :                           。

『Java仮想マシンの理解:JVMの高度な機能とベストプラクティス』では、次のように説明されています.
        volatile  ,        ,                 ,   “   ”                ,                  。            ,                       ,  ,  A          ,          ,      B   A                  ,         B  。

メインメモリについては、後で記事で紹介します.
上記の2つの段落から分かるように、volatileには良好な特性-可視性があり、可視性はすべてのスレッドが直ちに変数の値を得ることができることを理解することができる.したがって,マルチスレッドの場合,volatileで状態値を修飾することは非常に適している.
 
参考資料:
『Java理論と実践:Volatile変数を正しく使用する』
『Java仮想マシンの理解:JVMの高度な機能とベストプラクティス』