シングルトンモードを再確認してください。なぜシングルトンオブジェクトはvolatileキーワードを追加する必要があるのですか?

コード:

class Singleton{
    private volatile static Singleton instance = null;
    
    private Singletion{}

    public static Singleton getInstance(){
        if(instance==null){                        //#1
            synchronized(Singleton.class){         //#2
                if(instance==null){                //#3
                    instance = new Singletion();   //#4
                }else{
                    System.out.println("test");    //#5
                }
            }
        }
        return instance;
    }

}

 

シングルトンオブジェクトがvolatileキーワードを追加する必要があるのはなぜですか?2つの理由があります:

(1)可視性を確保します。

如果 "private static Singleton instance = null;":

1. Thread1が#1に入り、thread1のインスタンスがnull、thread1がCPUリソースをthread2に放棄します
。2。Thread2が#1に入り、thread2のインスタンスがnull、thread2がCPUリソースをthread1に
放棄します。3。Thread1が#2を実行します。#3、#4を順番に、そして最後にthread1でインスタンスをインスタンス化します。Thread1は実行を終了し、CPUリソースをthread2に渡します
。4。Thread2は#1を実行し、#1で取得されたインスタンスがまだnullであるため(そしてthread1からの最新のインスタンスが時間内に取得されなかったため)、#3に到達すると、したがって、Thread2は引き続き#3、#4を実行します
。5。最後に、thread1とthread2の両方がインスタンスをインスタンス化します。

 

如果 "private volatile static Singleton instance = null;":

1. Thread1が#1に入ると、thread1のインスタンスはnullになり(Javaメモリモデルはinstance(null)をメインメモリからthread1にコピーします)、thread1はCPUリソースをthread2に放棄します
。2。Thread2は#1に入ります。 thread2のインスタンスがnull(javaメモリモデルはinstance(null)をメインメモリからthread2にコピーします)、thread2はCPUリソースをthread1に放棄し
ます。3。Thread1は#2、#3、#4を順番に実行し、最後に、インスタンスはthread1でインスタンス化されます(これは揮発性の変更された変数であるため、メインメモリ内の変数にすぐに同期されます)。thread1が実行された後、CPUリソースをthread2に放棄します
。4。thread2、次に#1が実行され、#3に達すると、インスタンス(!= null)がメインメモリから再びコピーされるため、thread2はに直接実行されます。 #
5。5。最後に、thread2はインスタンスを繰り返しインスタンス化しなくなりました。

 

(2)再注文を防ぐ:

シングルトンモードでは、Instance instance = new Instance();はアトミック操作ではなく、アトミック命令の3つのステップに分割できます。

1.メモリアドレスを割り当てます。

2.新しいインスタンスオブジェクト。

3.メモリアドレスをインスタンスに割り当てます。

CPUが実行効率を向上させるために、これら3つの操作のシーケンスは123または132にすることができます。順序が132の場合、メモリアドレスがinstに割り当てられていると、シングルトンオブジェクトはinstが指すメモリアドレスで新しいものではありません。この時点で、インスタンスを取得すると、実際には空になり、nullポインタ例外が発生します。報告されます。

おすすめ

転載: blog.csdn.net/u012906122/article/details/103414518