理解--volatile JAVAフェイス質問

I.はじめに(私たちに揮発性のご理解を教えてください)

まず、Java仮想マシンが提供する軽量な同期メカニズムである揮発性、彼は基本的な規範を遵守しJMM。
JMMモデル:JMMメモリモデルの記述

第二に、三の大特性

揮発性がある三つの主要な機能は次のとおりです。可視性、順序(すなわち、禁止命令の並べ替え)を確保するためには、しかし、原子性を保証するものではありません。

視認性を確保するためには何ですか?

可視性:メインスレッドが物理メモリの値を変更し、他のスレッドはすぐにメインメモリの値を取得します。

命令の並べ替えを禁止

発注:コンパイラの性能を向上させるため、プロセッサに命令は、一般的に分かれて並び替え、実行します。
ソース- >コンパイラの最適化を再配置- >並列命令の並び替え- >再配置メモリシステム- >を命令の最後の実行

シングルスレッドの一貫性のある結果とコード配列の実装の結果を確実にするために、プログラムの最終的な実装内部環境。
プロセッサは、並べ替えの際に命令間のデータ依存性を考慮する必要があります

マルチスレッドにより存在する転位コンパイラの最適化に交互に実行環境は、一貫性を確保することができる2つのスレッドで使用される変数を決定することができないスレッドである、結果は予測できません。揮発性を追加した後、私たちは順番で物事を保つことができます。

アトミック性を保証するものではありません。

コードの検証は原子性を保証するものではありません。

public class volatileDemo {
    public static void main(String[] args) {
        MyData myData = new MyData();

        for (int i = 1; i <= 20; i++) {
            new Thread(() -> {
                for(int j=1;j<=1000;j++){
                    myData.addPlusPlus();
                    myData.addMyAtomic();
                }
            },String.valueOf(i)).start();
        }
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName()+"\tAtomicInteger type,final number"+myData.atomicInteger);
    }
}
class MyData{
    volatile int number = 0;//没有使用volatile,则最后结果不会是20000

    public void addT060(){
        this.number =60;
    }
    public void addPlusPlus(){
        number++;
    }

    AtomicInteger atomicInteger = new AtomicInteger();
    public void addMyAtomic(){
        atomicInteger.getAndIncrement();
    }

}

どのように解決するには?
1、プラスsynchonizedキーワード;
分析:あまりにも重い、適していません。
2、jucのAtomicIntegerを直接使用します。
atomicInteger.getAndIncrementは(); ++マルチスレッド環境の数の問題を解決し、CASの基本原理を。
CASの原則:CASの原則

揮発性が用いられる第3、?

再配置することができる命令の並べ替え、揮発性disableコマンドの追加がありますのでシングルトンDCLは、必ずしもDCLスレッド安全機構(ダブルロック機構をダブルエンドロックの対象を確認してください)。
スレッド内の特定のインスタンスは、最初のテストを実行する理由は、リードがnullでない場合、参照されるオブジェクトのインスタンスが初期化されなくてもよいです。
インスタンスが新しいSingletonDemoを()=; 3つのステップに分けることができます。

Memory = allocate(); //1.分配对象内存空间
Instance(memory); //2.初始化对象
Instance = memory;//3.设置instance指向刚分配的内存地址,此时instance!=null

図2及び図3は、シングルスレッドで変化しないプログラムの実行結果を再配置する前に、再配置およびかどうか、何の依存関係は存在しません。

リリース5元の記事 ウォンの賞賛0 ビュー47

おすすめ

転載: blog.csdn.net/qq_33805483/article/details/104099013