1. 程式人生 > >單例模式要點和幾種寫法

單例模式要點和幾種寫法

實現單例模式思路:一個類能返回物件一個引用(永遠是同一個)和一個獲得該例項的方法(必須是靜態方法,通常使用getInstance這個名稱);當我們呼叫這個方法時,如果類持有的引用不為空就返回這個引用,如果類保持的引用為空就建立該類的例項並將例項的引用賦予該類保持的引用;同時我們還將該類的建構函式定義為私有方法,這樣其他處的程式碼就無法通過呼叫該類的建構函式來例項化該類的物件,只有通過該類提供的靜態方法來得到該類的唯一例項。(來自維基百科)

總結一下要點:
1. 只能擁有一個物件
2. 建構函式私有 以保證不能建立多餘的物件。
3. 在類內建立一個物件,將其引用作為成員變數,但建構函式是 私有

的,無法new物件,只能將類內物件的引用加上static 修飾符,以保證可以直接用類載入呼叫。
4. 這個物件作為成員變數,一般為private,所以有對應的get 方法。
5. getInstance() 方法必須為靜態方法。

餓漢式

class Singleton {
    private Singleton() {}
    private static final Singleton singleton = new Singleton();
    public static Singleton getInstance() {
        return singleton;
    }
}

最簡單的一種寫法,類載入時直接new 出一個物件。

懶漢式 (延遲載入)

1 . 執行緒不安全寫法,多執行緒時可能會同時new 物件

class Singleton {
    private Singleton() {}
    private static Singleton singleton = null;
    public static Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }
        return
singleton; } }

2 . 執行緒安全寫法,但效率太低,一般不用

class Singleton {
    private Singleton() {}
    private static Singleton singleton = null;
    public static synchronized Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}

3 . 雙重校驗鎖,較常用,解決了執行緒問題和效率問題

class Singleton {
    private Singleton() {}
    private static Singleton singleton = null;
    public static Singleton getInstance(){
        if(singleton == null){
            synchronized(Singleton.class) {
                if(singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

4 . 靜態內部類 ,好像也比較常用

class Singleton {
    private Singleton() {
        System.out.println("singleton create");
    }
    private static class InstanceHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return InstanceHolder.INSTANCE;
    }
}