1. 程式人生 > >5.單例設計模式

5.單例設計模式

斷開 沒有 有一個 查看 餓漢 sync 線程池 即使 是否

 為什麽需要單例設計模式?

  我們在系統設計的時候,出於對性能,或者安全性等多種因素考慮,有些對象我們只需要一個。可能是全局只需要一個,也可能是整個系統只需要一個。

    這個時候我們就需要用到單例模式了。比如系統的配置文件。工具類,線程池,日誌對象等等。。。。

  類比一下。在過去是不是一個國家只能有一個皇帝。這個皇帝的生產就是必須通過一個單例模式對象來生產。

  單例設計模式說明:

  單例設計模式分析: 其實單例設計模式有六種,餓漢式,懶漢式,枚舉等等 記得面試這家公司的時候,有一道面試題就是:

    寫一個你認為最好的單例設計模式實現,當時我寫的就是雙重認證設計模式。這個是線程安全的設計模式。本篇文章主要介紹兩種單例設計模式:

    1.懶漢式 2.餓漢式 設計模式,並且會對這兩種設計模式記性對比,其他的充分理解這兩種設計模式之後。再後續文章中會進行補充。

  單例設計模式特點:

    單例類確保自己只有一個實例。
    單例類必須自己創建自己的實例。
    單例類必須為其他對象提供唯一的實例。

    

  實現:

    1.懶漢式

public class Singleton
    {
     //因為是懶漢所以剛開始沒有創建對象,只有在獲取對象的時候才去判斷是否有對象,有就直接返回,否者就創建對象然後返回 private static Singleton m_Instance; private Singleton() { // 將默認構造函數定義為私有,防止外部調用它實例化別的對象 } public static Singleton GetInstance() { if (m_Instance == null) { m_Instance = new Singleton(); } return m_Instance; } }

  2.惡漢式

    public class Singleton
    {
     //因為是惡漢式 所以上來就創建了一個對象,通過靜態公共方法獲取實例時候,判斷是否創建了實例,如果有就直接返回,否者就創建實例,然後返回。 private static Singleton m_Instance = new Singleton(); private Singleton() { // 將默認構造函數定義為私有,防止外部調用它實例化別的對象 } public static Singleton GetInstance() { return m_Instance; } }

  技術分享圖片

    說明對類圖中對象的關系不熟悉的可以查看我的第二篇文章。或者問讓度娘給你好好解釋一下。

  總結:

    相同點:

      1.都是有一個靜態私有本類成員變量

      2.都有一個私有構造函數

      3.都有一個靜態公有返回成員變量方法。

    不同點:

      1.惡漢式 比較餓 在定義靜態私有本類成員變量的時候就創建了對象 而 懶漢式比較懶,在返回對象的時候進行判斷,如果成員變量沒有指向才創建。

      

    懶漢模式和餓漢模式的優缺點:
      懶漢模式,它的特點是運行時獲得對象的速度比較慢,但加載類的時候比較快。它在整個應用的生命周期只有一部分時間在占用資源。
      餓漢模式,它的特點是加載類的時候比較慢,但運行時獲得對象的速度比較快。它從加載到應用結束會一直占用資源。
      這兩種模式對於初始化較快,占用資源少的輕量級對象來說,沒有多大的性能差異,選擇懶漢式還是餓漢式都沒有問題。但是對於初始化慢,占用資源多的重量級對象 來說,就會有比較明顯的差別了。所以,對重量級對象應用餓漢模式,類加載時速度慢,但運行時速度快;懶漢模式則與之相反,類加載時速度快,但運行時第一次獲 得對象的速度慢。
    從用戶體驗的角度來說,我們應該首選餓漢模式。我們願意等待某個程序花較長的時間初始化,卻不喜歡在程序運行時等待太久,給人一種反應遲鈍的感覺,所以對於有重 量級對象參與的單例模式,我們推薦使用餓漢模式。
    而對於初始化較快的輕量級對象來說,選用哪種方法都可以。如果一個應用中使用了大量單例模式,我們就應該權衡兩種方法了。輕量級對象的單例采用懶漢模式,減輕加 載 時的負擔,縮短加載時間,提高加載效率;同時由於是輕量級對象,把這些對象的創建放在使用時進行,實際就是把創建單例對象所消耗的時間分攤到整個應用中去 了,對於整個應用的運行效率沒有太大影響。

    安全性考慮:    

      主要是網上的一些說法,懶漢式的單例模式是線程不安全的,即使是在實例化對象的方法上加synchronized關鍵字,也依然是危險的、懶漢式是線程安全的。

    註意事項:

      只能使用單例類提供的方法得到單例對象,不要使用反射,否則將會實例化一個新對象。

不要做斷開單例類對象與類中靜態引用的危險操作。

多線程使用單例使用共享資源時,註意線程安全問題。

      單例設計模式的構造方法是私有的,不要嘗試去繼承他們。

    試用場景:

      需要頻繁實例化然後銷毀的對象。

創建對象時耗時過多或者耗資源過多,但又經常用到的對象。

有狀態的工具類對象。

頻繁訪問數據庫或文件的對象。

以及其他我沒用過的所有要求只有一個對象的場景

    大致上就總結這麽多了。當然關於單例模式遠不止這點東西。在掌握,理解這些東西的基礎上。可以在進行拓展學習。

  

5.單例設計模式