用代碼講清-單例模式(一)

什麼是單例模式?

單例模式顧名思義就是單個實例。比如各種Mgr,各種Factory,這樣的一個項目裏只需要有一個實例存在。話雖如此,我們封裝了這樣一個東西給別人用時,難保別人不會去new很多對象出來。所以,我們完全可以在代碼上保證他,只有一個實例存在。這就是單例模式。

常見的兩種形式

餓漢模式

示例代碼

public class Single01 {
    private static final Single01 INSTANCE = new Single01();

    //私有的構造方法,外部無法new對象
    private Single01() {
    }

    public static Single01 getInstance() {
        return INSTANCE;
    }
}

這裏我們根據上面的定義來測試一下,是否只有一個實例存在

    public static void main(String[] args) {
        Single01 single01 = Single01.getInstance();
        Single01 single011 = Single01.getInstance();
        System.out.println(single01 == single011);
    }

測試是否只有一個實例
輸出結果爲:true
結論:該方式編寫的單例模式,只有一個實例存在

懶漢模式

示例代碼

public class Single02 {
    private static Single02 INSTANCE;

    private Single02() {
    }
    private static Single02 getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Single02();
        }
        return INSTANCE;
    }
 }

再來看下這形式的是否依然滿足 只有一個實例存在

 private static Single02 getInstance() {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //此處線程不安全
        if (INSTANCE == null) {
            INSTANCE = new Single02();
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> System.out.println(Single02.getInstance().hashCode())).start();
        }
    }

我們知道在同一個類中同一個對象的hashCode是相同的。
測試是否只有一個實例
輸出結果:存在hashCode不一致的情況

結論

懶漢模式,在多線程的情況下,會重複new對象。所以我們在使用單例模式的時候,最好使用第一種形式。

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