Java設計模式~單例模式

單例模式

單例(Singleton)模式的定義:一個類有且僅有一個實例,並且自行實例化向整個系統提供。例如,Windows 中只能打開一個任務管理器,這樣可以避免因打開多個任務管理器窗口而造成內存資源的浪費,或出現各個窗口顯示內容的不一致等錯誤。

在計算機系統中,還有 Windows 的回收站、操作系統中的文件系統、多線程中的線程池、顯卡的驅動程序對象、打印機的後臺處理服務、應用程序的日誌對象、數據庫的連接池、網站的計數器、Web 應用的配置對象、應用程序中的對話框、系統中的緩存等常常被設計成單例。

單例模式有 3 個特點:

  • 單例類只有一個實例對象;

  • 該單例對象必須由單例類自行創建;

  • 單例類對外提供一個訪問該單例的全局訪問點;

1、飢餓式單例

該模式的特點: 類一旦加載就創建一個單例,保證在調用 getInstance 方法之前單例已經存在了。

是否 Lazy 初始化

是否多線程安全

實現難度:簡單

優點:沒有加鎖,執行效率會提高。

缺點:類加載時就初始化,浪費內存。

代碼如下:

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton() {
    }
    public static Singleton getInstance() {
        return instance;
    }
}

 

2、懶漢式單例

該模式的特點:類加載時沒有生成單例,只有當第一次調用 getlnstance 方法時纔去創建這個單例。

是否 Lazy 初始化:是

是否多線程安全:是

實現難度:複雜

描述:這種方式採用雙重加鎖機制,安全且在多線程情況下能保持高性能。

getInstance() 的性能對應用程序很關鍵。

代碼如下:

public class Singleton {
    private volatile static Singleton instance = null;////保證 instance 在所有線程中同步

    private Singleton() {//private 避免類在外部被實例化
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {//使用synchronized關鍵字來同步獲取實例,保證單例的唯一性
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

從上述代碼可以看到,雙重加鎖中有兩次判斷。第一次檢查是避免不必要的上鎖。相對加鎖的懶漢模式而言,第二次檢查是,在給當前線程加鎖後,例行檢查更加安全。

3、枚舉

默認枚舉實例的創建是線程安全的,並且在任何情況下都是單例。實際上

  • 枚舉類隱藏了私有的構造器。

  • 枚舉類的域 是相應類型的一個實例對象

是否 Lazy 初始化:

是否多線程安全:

實現難度:簡單

描述:這種實現方式還沒有被廣泛採用,但這是實現單例模式的最佳方法。它更簡潔,自動支持序列化機制,絕對防止多次實例化。這種方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不僅能避免多線程同步問題,而且還自動支持序列化機制,防止反序列化重新創建新的對象,絕對防止多次實例化。不過,由於 JDK1.5 之後才加入 enum 特性,用這種方式寫不免讓人感覺生疏,在實際工作中,也很少用。不能通過 reflection attack 來調用私有構造方法。

代碼如下:

public enum Singleton {
    INSTANCE;   
    public void doSomethingMethod() {
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章