單例模式(Singleton Pattern)

設計模式大概算是過了一遍了,但總體來說還不是很清楚,因此想在這裏全面的總結一下。

因爲之前學設計模式的時候是用C++寫的,在這裏就不再用C++再寫一遍了,所以本體系中的所有設計模式都將會以java代碼實現,有興趣的讀者可以自行用C++實現。

OK,話不多說,先從單例模式開始。

單例模式是最簡單的設計模式之一,這種設計模式是一種創建型的模式,提供了創建對象的最佳方式。

單例模式顧名思義就是一個類只允許創建一個實例,因此它只涉及到一個單一的類,並且這個類要完成自己創建自己的實例的工作,並保證能且只能創建一個實例。這個類還需要提供一個訪問這個實例的方法。

接下來我們分析一下單例模式的多種實現方式。(以下代碼均爲Java實現,若讀者有興趣可自行用C++實現)

一、懶漢形式(延遲加載)

public class Singleton{
    private static Singleton singleton;//定義一個未初始化的私有靜態對象,外部不可訪問

    //構造私有,保證外部不可創建實例
    private Singleton() {
    }

    //提供公有方法獲取實例
    public synchronized static Single newInstance() {
        if (singleton== null) {
            singleton= new Singleton();//如果singleton爲空就爲其創建實例
        }
        return singleton;//將創建好的實例返回
    }
}

懶漢形式是標準的單例實現形式,它的延遲加載體現在newInstance方法裏的判斷,方法加了synchronized關鍵字可以避免多線程問題,但會影響程序性能。

二、餓漢形式(貪婪加載)

public class Singleton {
    private static Singleton singleton= new Singleton();//直接創建私有靜態實例

    //構造方法私有保證外部不可創建實例
    private singleton() {
    }

    public static Singleton newInstance() {
        return singleton;//將創建好的實例返回
    }
}

在單例對象聲明的時候就直接初始化對象,可以避免多線程問題,但是如果對象初始化比較複雜,會導致程序初始化緩慢。

三、雙重鎖檢查

public class Singleton {
    private volatile static Singleton singleton;

    private Singleton() {
    }

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

這個是懶漢形式的加強版,將synchronized關鍵字移到了newInstance方法裏面,同時將singleton對象加上volatile關鍵字,這種方式既可以避免多線程問題,又不會降低程序的性能。但volatile關鍵字也有一些性能問題,不建議大量使用。

四、Lazy initialization holder class

public class Singleton {
    private static class SingletonHolder {
        private static Singleton singleton = new Singleton();
    }

    private Singleton() {
    }

    public static Singleton newInstance() {
        return SingletonHolder.singleton;
    }
}

這裏創建了一個內部靜態類,通過內部類的機制使得單例對象可以延遲加載,同時內部類相當於是外部類的靜態部分,所以可以通過jvm來保證其線程安全。這種形式比較推薦。

五、枚舉

public enum Singleton {
    singleton
}
單因素的枚舉類已經實現了單例,這種方法更加簡單。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章