設計模式——單例模式

歡迎轉載,請附出處:
http://blog.csdn.net/as02446418/article/details/47952947

單例模式(Singleton)

首先來明確一個問題,那就是在某些情況下,有些對象,我們只需要一個就可以了,

比如,一臺計算機上可以連好幾個打印機,但是這個計算機上的打印程序只能有一個,

這裏就可以通過單例模式來避免兩個打印作業同時輸出到打印機中,

即在整個的打印過程中我只有一個打印程序的實例。

簡單說來,單例模式(也叫單件模式)的作用就是保證在整個應用程序的生命週期中,

任何一個時刻,單例類的實例都只存在一個(當然也可以不存在)。

單例模式的結構圖

這裏寫圖片描述

從上面的類圖中可以看出,在單例類中有一個構造函數 Singleton ,

但是這個構造函數卻是私有的(前面是“ - ”符號),

然後在裏面還公開了一個 GetInstance()方法,

通過上面的類圖不難看出單例模式的特點,從而也可以給出單例模式的定義

單例模式保證一個類僅有一個實例,同時這個類還必須提供一個訪問該類的全局訪問點。

下面來看代碼:

public class Singleton1 {
    private static Singleton1 instance;
    private Singleton1(){
        System.out.println("我是線程不安全的餓漢singleton");
    }

    public static Singleton1 getSingleton1(){
        if (instance==null) {
            instance = new Singleton1();
        }

        return instance;
    }


}

如上面代碼所示,這種寫法是最不推薦的,也是因爲它的線程不安全,我們來看一下測試代碼和運行結果:

線程不安全的singleton

public class SingletonTest {
    public static void main(String[] args){

        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    Singleton1.getSingleton1();

                }
            }).start();
        }

    }
}

這裏寫圖片描述

這裏new了三個singleton,在多線程環境下可能存在多個線程判斷instance==null,所以會分別new出自己的instance,這顯然違背了單例模式的初衷。

接下來我們換種寫法:

線程安全的餓漢singleton

public class Singleton2 {
    private static Singleton2 instance = new Singleton2();
    private Singleton2(){
        System.out.println("我是線程安全的餓漢singleton");
    }

    public static Singleton2 getSingleton1(){

        return instance;
    }

}

下面是運行結果:
這裏寫圖片描述

爲什麼說是餓漢的singleton,因爲如上面代碼所示,在用到示例instance之前就已經把它初始化好了,雖然這裏是線程安全的,但是也會影響性能,所以我們來看第三種singleton。

線程安全的懶漢singleton

public class Singleton {
    private Singleton(){
        System.out.println("我是線程安全的singleton");
    }

    private static class singletonHolder{
        private final static Singleton instance = new Singleton();
    } 


    public static Singleton getSingleton(){
        return singletonHolder.instance;
    }

}

下面是運行結果:
這裏寫圖片描述

如上述代碼所示,這裏用到了singletonHolder這個內部類,這個內部類只會在singletonHolder.instance中用到,也就是用的時候纔會初始化,故稱爲懶漢singleton,這樣既解決了多線程下不安全的問題,同時也解決了提前初始化影響的性能問題,所以是最推薦的一種寫法。

發佈了80 篇原創文章 · 獲贊 141 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章