java設計模式(一)創建型模式之 單例模式(餓漢式,懶漢式,線程安全,雙重檢查)

1.介紹

    單例模式是一種常用的軟件設計模式,其定義是單例對象的類只能允許一個實例存在。 

2.實現思路與步驟

  1).將該類的構造方法定義爲私有方法,這樣其他處的代碼就無法通過調用該類的構造方法來實例化該類的對象,只有通過該類提供的靜態方法來得到該類的唯一實例;

  2).在該類內提供一個靜態方法,當我們調用這個方法時,如果類持有的引用不爲空就返回這個引用,如果類保持的引用爲空就創建該類的實例並將實例的引用賦予該類保持的引用。

2.單例模式實現

   1)、餓漢式  

public class Singleton {

    private final static Singleton instance= new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return instance;
    }
}

 優點:這種寫法比較簡單,就是在類裝載的時候就完成實例化。避免了線程同步問題。

 缺點:在類裝載的時候就完成實例化,沒有達到延遲加載的效果。如果從始至終從未使用過這個實例,則會造成內存的浪費。

 2)、懶漢式

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

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

優點:這種寫法起到了延遲加載的效果,僅適合於單線程環境

缺點: 如果在多線程下,一個線程進入了if (singleton == null)判斷語句塊,還未來得及往下執行,另一個線程也通過了這個判斷語句,這時便會產生多個實例

3)、懶漢式(線程安全,同步方法)

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

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

優點:解決了線程不安全的問題

缺點: 效率低,每個線程都要執行getInstance()方法進行同步。而其實這個方法只執行一次實例化代碼就夠了,後面的想獲得該類的實例,直接return就行了

5) 雙重檢查

public class Singleton {

    private static volatile Singleton singleton;

    private Singleton() {}

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

       雙重檢測概念對於多線程開發者來說不會陌生,如代碼中所示,我們進行了兩次if (singleton == null)檢查,這樣就可以保證線程安全了。這樣,實例化代碼只用執行一次,後面再次訪問時,判斷if (singleton == null),直接return實例化對象。

優點:線程安全;延遲加載;效率較高。

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