JAva単例モードsingletonレビュー、単例モードの実現方法

5107 ワード

最近の面接では、単例パターンに関する知識を使いましたが、ここでまとめてみると、温故知新です.
単例モードはjava開発でよく使われるモードです.通常、プログラムの実行中にインスタンスオブジェクトが1つしか生成されないことを指します.シングル・インスタンス・モードには、通常、次のような適用シーンがあります.
1、ハード需要、例えばプリンタの印刷機能;
2、システムのオーバーヘッドを低減します.例えば、プログラムの実行中に、あるクラスのインスタンスを頻繁に作成する可能性があります.単一のインスタンスモードでは、クラスのインスタンスを一度だけ作成することができ、システムのオーバーヘッドを低減することができます.
以上の解析により,単一パターン(singleton)のいくつかの特徴を大まかにまとめることができる.
1、グローバルなのでstat icで修飾します
2,プライベートな構造方法とプライベートなクラスオブジェクトは,外部クラスがnew 1つのオブジェクトまたは直接クラスオブジェクトを呼び出すことができないことを保証する.
3,外部クラス呼び出しのための共通のメンバーメソッドを暴露する
どのような単例モードでも,実際の状況と結びつけて設計する必要があると述べた.そのため、多くの単例モードの実現方法が生まれ、以下のいくつかがあります.
1、怠け者式単例モード
2,餓漢式単例モード
3,スレッドセキュリティの一例モード
4,静的内部クラス単例モード
5,列挙単例モード
1、怠け者式単例モード
怠け者式単例モードは、オブジェクトの遅延ロードを実現し、システム負荷を低減することができる.これらのポイントに基づいて、このようなクラスSingleTonを設計することができます.
public class SingleTon {
	/**
	 *        singleton  
	 * 
	 *     :
	 * 1,   ,    static     
	 * 2,              ,           new             
	 * 3,           ,      
	 * 
	 */
	
	//1,       
	private SingleTon(){
		
	}
	
	//2,   、       
	private static SingleTon singleTonInstance = null;
	
	//3,           ,      
	public static SingleTon getSingleTonInstance(){
		
		//         
		if(singleTonInstance == null){
			
			//    
			singleTonInstance = new SingleTon();
			
		}
		
		return singleTonInstance;
		
	}

}

対照的に、普通のjavaクラスをもう一つ書きます.
<span style="font-size:14px;">public class NotSingleTon {
	
	//1,    ,       ,     
	public NotSingleTon(){
	
	}
	
}</span>

テストしてみましょう
<span style="font-size:14px;">package com.java.test;

public class SingleTonTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//      
		//static            ,              
		SingleTon singleTonInstance_1 = SingleTon.getSingleTonInstance();
		SingleTon singleTonInstance_2 = SingleTon.getSingleTonInstance();
		//    
                System.out.println("singleTonInstance_1.hashCode() = " + singleTonInstance_1.hashCode());
                System.out.println("singleTonInstance_2.hashCode() = " + singleTonInstance_2.hashCode());
        
                //       
                NotSingleTon notsingleTonInstance_1 = new NotSingleTon();
                NotSingleTon notsingleTonInstance_2 = new NotSingleTon();
        
                //    
                System.out.println("notsingleTonInstance_1.hashCode() = " + notsingleTonInstance_1.hashCode());
                System.out.println("notsingleTonInstance_2.hashCode() = " + notsingleTonInstance_2.hashCode());

	}

}
</span>

印刷局の出力結果:
<span style="font-size:14px;">singleTonInstance_1.hashCode() = 29115481
singleTonInstance_2.hashCode() = 29115481
notsingleTonInstance_1.hashCode() = 4872882
notsingleTonInstance_2.hashCode() = 25724761
</span>

上記の書き方は、怠け者式の単例モードです.利点は,オブジェクトの遅延ロードを実現し,システムオーバーヘッドを低減できることである.欠点は、マルチスレッド環境でオブジェクトを繰り返し作成する可能性があるスレッドセキュリティの問題です.
2,餓漢式単例モード
次に、餓漢式の単例パターンを見てみましょう.
public class SingleTon {
	
	//1,       
	private SingleTon(){
		
	}
	
	//2,      
	private static SingleTon singleTonInstance = new SingleTon();
	
	//3,           ,      
	public static SingleTon getSingleTonInstance(){
		
	    return singleTonInstance;
		
	}

}

これは、インスタンスを最初にロードするときに、実際にすぐにこのオブジェクトを作成する必要があるかどうかにかかわらず、インスタンスのオブジェクトを作成する餓漢式の単一のインスタンスモードです.
3,スレッドセキュリティの一例モード
マルチスレッド環境では、スレッドセキュリティは考慮しなければならない問題です.
public class SingleTon {
<pre name="code" class="java" style="font-size: 14px;">    //<span style="font-family: Arial, Helvetica, sans-serif;">       </span>
    private SingleTon(){
    }
 
 
    //   、   、volatile SingleTon  
    private static volatile SingleTon singleTonInstance = null;
    
    public static SingleTon getSingleTonInstance(){
        if(singleTonInstance == null){
            synchronized (SingleTon.class){
                if(singleTonInstance == null){
                    singleTonInstance = new SingleTon();
                }
            }
        }
        return singleTonInstance;
    }    
}

4,静的内部クラス単例モード
静的内部クラスは1回しかロードされないため,スレッドが安全であることが分かった.
public class SingleTon {
    //     
    private static class Holder {
        private static SingleTon singleTonInstance = new SingleTon();
    }
    //       
    private SingleTon(){
    }
        
    public static SingleTon getSingleTonInstance(){
        return Holder.singleTonInstance;
    }
}

上記の4つの方法は,実装された単一のモードに共通の欠陥があり,javaの反射メカニズムを回避できず,新しいオブジェクトを作成することである.反射メカニズムによって新しいオブジェクトが作成されるのを避けるには、クラスを列挙する必要があります.
さあ、今日はしばらくここまで話して、またお話しします.