Javaにおける二重検出失敗(DCL)の原因
768 ワード
最も簡単で最も理解しやすい解釈方法(正確ではないかもしれません)は、次のようになります.
Object a = new Object();
Objectオブジェクトの作成中に2つの値ドメインm 1とm 2を初期化する必要があると仮定すると、通常のプロセスは、オブジェクトの作成を開始し、1つのオブジェクトハンドルを得、m 1を初期化し、m 2を初期化し、このオブジェクトハンドルを変数aに付与することである.
しかし、並べ替えの存在により、実際の実行過程は、オブジェクトの作成を開始し、オブジェクトハンドルを得、m 1を初期化し、このオブジェクトハンドルを変数a,m 2に付与して初期化することになる可能性がある.もう一つのスレッドは、このオブジェクトハンドルが変数aに付与された後、m 2を初期化して変数aにアクセスし、aを通じてこの作成中のオブジェクトにアクセスします.ほら、問題が発生しました.m 2の初期化はまだ完了していません.
クラスローダ遅延ロード
Object a = new Object();
Objectオブジェクトの作成中に2つの値ドメインm 1とm 2を初期化する必要があると仮定すると、通常のプロセスは、オブジェクトの作成を開始し、1つのオブジェクトハンドルを得、m 1を初期化し、m 2を初期化し、このオブジェクトハンドルを変数aに付与することである.
しかし、並べ替えの存在により、実際の実行過程は、オブジェクトの作成を開始し、オブジェクトハンドルを得、m 1を初期化し、このオブジェクトハンドルを変数a,m 2に付与して初期化することになる可能性がある.もう一つのスレッドは、このオブジェクトハンドルが変数aに付与された後、m 2を初期化して変数aにアクセスし、aを通じてこの作成中のオブジェクトにアクセスします.ほら、問題が発生しました.m 2の初期化はまだ完了していません.
クラスローダ遅延ロード
public class Singleton {
private static class Holder {
static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return Holder.instance;
}
}