java設計模式——單例模式

單例模式

1、單例模式解決的問題:保證一個類在內存中的對象唯一性。
比如:多程序讀取一個配置文件時,建議配置文件封裝成對象。會方便操作其中數據,又要保證多個程序讀到的是同一個配置文件對象,就需要該配置文件對象在內存中是唯一的。

2、如何保證對象唯一性呢?
2.1 不讓其他程序創建該類對象。
2.2 在本類中創建一個本類對象。
2.3 對外提供方法,讓其他程序獲取這個對象。

3、使用單例設計模式的好處
3.1 控制資源的使用,通過線程同步來控制資源的併發訪問
3.2 控制實例產生是數量,達到節約資源的目的
3.3 作爲通信媒介使用,也就是數據共享,它可以在不建立直接關聯的條件下,讓多個不相關的兩個線程或者進程之間通信

4、單例模式設計步驟
4.1 因爲創建對象都需要構造函數初始化,只要將本類中的構造函數私有化,其他程序就無法再創建該類對象;
4.2 就在類中創建一個本類的對象;
4.3 定義一個方法,返回該對象,讓其他程序可以通過方法就得到本類對象。(作用:可控)

5、代碼實現(分兩種:餓漢式和懶漢式)

餓漢式:

class Single{
    private Single(){} //私有化構造函數。
    private static Single s = new Single(); //創建私有並靜態的本類對象。
    public static Single getInstance(){ //定義公有並靜態的方法,返回該對象。
        return s;
    }
}

特點:餓漢式是線程安全的,在類創建的同時就已經創建好一個靜態的對象供系統使用,以後不在改變

懶漢式:

class Single2{
    private Single2(){}
    private static Single2 s = null;
    public static Single2 getInstance(){
        if(s==null)
            s = new Single2();
        return s;
    }
}

特點:延遲加載,需要的時候才使用。
缺點:單線程使用是沒問題的,但是我們的web開發都是需要併發的,不是線程安全的。

6、爲什麼說上述懶漢式不是線程安全的

從線程安全性上講,不加同步的懶漢式是線程不安全的。
比如,有兩個線程,一個是線程A,一個是線程B,它們判斷條件滿足都進來了,它們同時調用getInstance方法,那就可能導致併發問題。
當A、B線程併發的情況下,會創建出兩個實例來,這樣單例的控制在併發情況下就失效了。

7、懶漢式線程安全問題解決
懶漢式一般要用雙重檢查加鎖判斷

class Single {
    private static Single s = null;

    private Single() {
    }

    public static Single getInstance() {
        //檢查實例是否存在,如果不存在進入下面的synchronized代碼塊
        if (s == null) {
            synchronized (Single.class) {
                if (s == null)// 拿到鎖後再次判斷實例是否存在,如果不存在才創建實例
                    s = new Single();
            }
        }
        return s;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章