單例模式主要用的做用是用於保證程序運行中某個類只有一個實例,並提供一個全局入口點。單例模式(Singleton)爲GOF闡述的標準24種設計模式中最簡單的一個。但隨着時間推移,GOF所闡述的單例實現已不能徹底知足實際應用。html
"ensure a class has only one instance, and provide a global point of access to it"設計模式
幾乎在每一個應用程序中,都須要有一個從中進行全局訪問和維護某種類型數據的區域。 在面向對象的 (OO) 系統中也有這種狀況,在此類系統中,在任何給定時間只應運行一個類或某個類的一組預約義數量的實例。安全
一、當使用某個類來維護增量計數器時,此簡單的計數器類須要跟蹤在多個應用程序領域中使用的整數值。 此類須要可以增長該計數器並返回當前的值。 對於這種狀況,所需的類行爲應該僅使用一個類實例來維護該整數,而不是使用其它類實例來維護該整數。
二、每臺計算機能夠有若干個打印機,但只能有一個Printer Spooler,避免兩個打印做業同時輸出到打印機。
三、PC機中可能有幾個串口,但只能有一個COM1口的實例。
四、系統中只能有一個窗口管理器。
5.NET Remoting中服務器激活對象中的Sigleton對象,確保全部的客戶程序的請求都只有一個實例來處理。
6.應用程序的日誌應用,通常都何用單例模式實現,這通常是因爲共享的日誌文件一直處於打開狀態,由於只能有一個實例去操做,不然內容很差追加。服務器
一、單線程實現多線程
單線程單例模式實現
能夠說是一個標準的單例的代碼。併發
優勢:ide
因爲實例是在 Instance 屬性方法內部建立的,所以類可使用附加功能(例如,對子類進行實例化),即便它可能引入不想要的依賴性。函數
直到對象要求產生一個實例才執行實例化;這種方法稱爲"懶實例化"。懶實例化避免了在應用程序啓動時實例化沒必要要的 singleton。優化
缺點:this
多線程環境下它是不安全的。若是執行過程的不一樣線程同時進入 Instance 屬性方法,那麼可能會建立多個 Singleton 對象實例。每一個線程都會執行下列語句,並決定必須建立新的實例。
二、多線程實現
多線程單例模式實現
優勢:因爲實例的產生由本身控制,能夠對非默認構造函數進行擴展、傳參等操做。
缺點:實現相對複雜
三、C#簡潔版
因爲 C# 與公共語言運行庫也提供了一種"靜態初始化"方法,這種方法不須要開發人員顯式地編寫線程安全代碼,便可解決多線程建立等問題。
簡潔實現1
更簡潔的方式:
簡潔實現1
由於靜態構造函數是屬於類的,而不屬於任何一個實例,因此這個構造函數只會被執行一次,並且是在建立此類的第一個實例或引用任何靜態成員以前,由.NET自動調用。
一、因爲靜態構造函數由.NET調用,因此不須要public和private等訪問修飾符。
二、在建立第一個類實例或任何靜態成員被引用時,.NET將自動調用靜態構造函數來初始化類。(咱們沒法調用,也不知道它什麼時候被調用)
三、靜態構造函數屬於類,構造函數屬於實例,他們並不衝突。靜態構造函數只會運行一次。
缺點:因爲在此解決方案中由 .NET Framework 負責執行初始化,沒法在實例化以前使用非默認的構造函數或執行其餘任務。在大多數狀況下,靜態初始化是在.NET 中實現 Singleton 的首選方法。
單線程版、多線程版、簡潔版有各自的應用,沒有那種實現是最好的。
總結上述三種實現方法,以是否須要在建立單例實例時傳參或執行其餘任務分兩類。即:
一、不須要執行其餘任務
使用簡潔版便可以保障在單線程、多線程都能安全使用的同時,代碼量較少。
二、須要
通常狀況下,均爲單線程版。則使用單線程建立。若程序有多線程應用則應用使用雙重檢測的多線程實現。
參考文檔:
http://msdn.microsoft.com/zh-cn/library/ff650316.aspx
http://terrylee.cnblogs.com/archive/2005/12/09/293509.html