1. 程式人生 > >單例模式學習筆記

單例模式學習筆記

單例模式 模式概念:確保一個類只有一個例項,並提供一個全域性訪問點 要點: (1)單件模式確保程式中一個類最多隻有一個例項。 (2)單件模式也提供訪問這個例項的全域性點。 (3)在Java中實現單件模式需要私有的構造器、一個靜態方法和一個靜態變數。 (4)確定在效能和資源上的限制,然後小心地選擇適當的方案來實現單件,以解決多執行緒問題(我們必須認定所有的程式都是多執行緒的)。 (5)如果不採用第5版的Java 2,雙重檢查加鎖實現會失效。 (6)小心,你如果使用多個類載入器,可能導致單件失效而產生多個例項。 (7)如果使用JVM 1.2或之前的版本,你必須簡歷單件登錄檔,以免垃圾收集器將單件回收。
/**
 * 簡單單例模式,延遲建立例項
 * 無法解決多執行緒訪問問題
 */
public class Singleton {  
    /*利用一個靜態變數來記錄Singleton類的唯一例項*/
    private static Singleton uniqueInstance;  
    /*把構造器宣告為私有的,只有自Singleton類內才可以呼叫構造器*/
    private Singleton(){};  

    public static Singleton getInstance() {  
        if(uniqueInstance == null) {  
            uniqueInstance = new Singleton();  
        }  
        return uniqueInstance;  
    }
}
/** 
 * 使用同步的方法,解決多執行緒災難 
 * 但只有第一次執行此方法時,才需要真正的同步
 * 一旦設定好uniqueInstance變數,就不再需要同步方法了
 * 這種方法會影響程式執行效率 
 */ 
public class Singleton {  
    /*利用一個靜態變數來記錄Singleton類的唯一例項*/
    private static Singleton uniqueInstance;  
    /*把構造器宣告為私有的,只有自Singleton類內才可以呼叫構造器*/
    private Singleton(){};  

    public static synchronized Singleton getInstance() { 
        if(uniqueInstance == null) { 
            uniqueInstance = new Singleton(); 
        } 
        return uniqueInstance; 
    }  
}
/** 
 * 使用“急切”建立例項,而不用延遲例項化的做法
 * 如果程式總是建立並使用單件例項,或者在建立和執行的負擔不太繁重,可以採用此方法 
 */  
public class Singleton {  
    /*利用一個靜態變數來記錄Singleton類的唯一例項*/
	private static Singleton uniqueInstance = new Singleton(); 
    /*把構造器宣告為私有的,只有自Singleton類內才可以呼叫構造器*/
    private Singleton(){};  

    public static Singleton getInstance() { 
        return uniqueInstance; 
    }  
}
/** 
 * 用“雙重檢查加鎖”,在getInstance()中減少使用同步 
 * 如果效能是你關心的重點,這種做法可以幫你大大減少getInstance()的時間耗費
 * volatile關鍵詞確保,當uniqueInstance變數被初始化成Singleton例項時多個執行緒能正確處理uniqueInstance變數
 * 兩次null檢查是為了防止2個執行緒同時發現instance==null,然後同時呼叫同步塊,產生二次例項化
 * 兩次null檢查後,第二個進入syncInit的執行緒將發現那個物件已經不再是null了
 */
public class Singleton {  
    /*利用一個靜態變數來記錄Singleton類的唯一例項*/
	private volatile static Singleton uniqueInstance;  
    /*把構造器宣告為私有的,只有自Singleton類內才可以呼叫構造器*/
    private Singleton(){};  
 
    public static Singleton getInstance() { 
        if(uniqueInstance == null) { 
            synchronized (Singleton.class) { 
            	/*進入區塊後,再檢查一次,如果仍是null,才建立例項*/
                if(uniqueInstance == null) { 
                    uniqueInstance = new Singleton(); 
                } 
            } 
        }
        return uniqueInstance;
    }  
}