JAVAの3種類の実現単例モード方法(二):静的内部クラスを用いて単例設計モードを実現する


静的コードブロックと静的内部クラスのロード順序:外部クラスの構築関数を呼び出すと、外部クラスの静的コードブロックは同時にロードされますが、その内部クラスは同時にロードされません.内部クラスの静的ドメインまたはその構築方法またはその静的方法が呼び出された場合にのみ、内部にロードされます.
従って,内部で単一の例を実現することで,遅延負荷を実現できる.
このソリューションはLazy initialization holder classモードと呼ばれ,javaのクラスレベル内部クラスとマルチスレッドデフォルト同期ロックの知識を総合的に用い,遅延ロードとスレッドセキュリティを巧みに同時に実現した.
1対応する基礎知識(1)クラスクラスクラス内部クラスとは?簡単に言えば、クラス内部クラスとは、static修飾のあるメンバー内部クラスを指す.static修飾のないメンバー式内部クラスを対象クラス内部クラスと呼ぶ.(2)クラスレベル内部クラスは、その外部クラスのstatic成分に相当し、そのオブジェクトと外部クラスオブジェクトとの間に依存関係がないため、直接作成することができる.オブジェクトレベル内部クラスのインスタンスは、外部オブジェクトインスタンスにバインドされている.(3)クラスクラスクラス内クラスでは、静的メソッドを定義できます.静的メソッドでは、外部クラスの静的メンバーメソッドまたは変数のみが参照できます.(4)クラス内クラスは、その外部クラスのメンバーに相当し、初めて使用されたときにのみマウントされます.
マルチスレッドデフォルト同期ロックの知識:マルチスレッド開発では、synchronizedを使用して相互反発ロックを追加して同期制御を行うことが主な同時問題を解決するために行われていますが、場合によってはJVMが同期制御を暗黙的に実行している場合があります.これらの場合、自分で同期制御を行う必要はありません.これらには、(1)静的初期化器(静的フィールドまたはstatic{}ブロック内の初期化器)によってデータが初期化された場合、(2)finalフィールドにアクセスした場合、(3)スレッドの作成前にオブジェクトが作成された場合、(4)スレッドが処理するオブジェクトが表示された場合が含まれる.
2ソリューションの考え方(1)簡単にスレッドのセキュリティを実現するためには、JVMによってスレッドのセキュリティを保証する静的イニシエータ方式を採用することができます.例えば、餓漢式の実装方式です.しかし、これでは、一定のスペースを浪費するのではないでしょうか.この実装方式では、クラスがロードされたときにオブジェクトをイニシャル化するので、必要かどうかにかかわらず.(2)クラスがロードされたときにオブジェクトを初期化しない方法がある場合、問題は解決されるのではないでしょうか.1つの実行可能な方法は、クラスレベルの内部クラスを採用し、このクラスレベルの内部クラスでオブジェクトインスタンスを作成することです.これにより、このクラスレベルの内部クラスを使用しない限り、オブジェクトインスタンスは作成されず、遅延ロードとスレッドが同期して実現されます安全です.
//      .      ,          
public class Singleton1 {  
    private Singleton1() {}  
    private static final Singleton1 single = new Singleton1();  
    //         
    public static Singleton1 getInstance() {  
        return single;  
    }  
} 

3.彼が怠惰なロードをどのように表現しているかを補足します.内部の静的クラスは参照があってからメモリにロードされます.だから、getInstance()を初めて呼び出す前に、SingletonHolderはロードされていません.getInstance()を初めて呼び出した後だけ、return SingletonHolderに関連しています.instance; SingletonHolderへの参照が生成され、内部静的クラスのインスタンスが実際にマウントされます.これはつまり怠惰なロードの意味です.
「JVMはスレッドの安全性を保証する」という言葉の意味:classloaderのメカニズムを利用してinstanceの初期化時に1つのスレッドしかないことを保証しているので、スレッドも安全であり、性能損失もない.
抜粋:http://blog.sina.com.cn/s/blog_6d2890600101gb8x.html,静的内部クラスの解釈
package instance.innerClass;
public class InstanceInnerClass {
        private String str;
	private Long currentTime;
	
	private static class InnerClass {
		private static final InstanceInnerClass instance = new InstanceInnerClass();
	}
	
	public static InstanceInnerClass getInstance() {
		return InnerClass.instance;
	}
	
	private InstanceInnerClass() {
		initProperties();
	}
	
	private void initProperties() {
		this.str = "hello world!";
		this.currentTime = System.currentTimeMillis();
	}
	
	public void print() {
		System.out.println("time:" + currentTime + " >>> " + str );
	}

	public static void main (String[] args) {
		for (int i = 0; i < 3; i++) {
			new Thread( new Runnable() {
				@Override
				public void run() {
					InstanceInnerClass instance = InstanceInnerClass.getInstance();
					System.out.println("hashCode:" + instance.hashCode());
					instance.print();
				}
			}).start();
		}
	}
}

その他:
静的内部クラスを使用して、単一の設計モードを実装します.http://www.cnblogs.com/zeng1994/p/7397637.html
朝花夕拾い-Java静的内部クラスロード:https://blog.csdn.net/zhang_yanye/article/details/50344447
内部クラスのロード順序および静的内部クラスの単一モード:https://blog.csdn.net/zmx729618/article/details/69227762