深入理解設計模式(一) 單例模式

2022-05-26 16:00:10 字數 2821 閱讀 9956

本文首先概述了單例模式,揭示了單例模式的應用場景和優缺點,最後我們給出了單例模式的幾種實現方式及注意事項。

單例模式是一種常用的軟體設計模式,其定義是單例物件的類只能允許乙個例項存在。

許多時候整個系統只需要擁有乙個的全域性物件,這樣有利於我們協調系統整體的行為。比如在某個伺服器程式中,該伺服器的配置資訊存放在乙個檔案中,這些配置資料由乙個單例物件統一讀取,然後服務程序中的其他物件再通過這個單例物件獲取這些配置資訊。這種方式簡化了在複雜環境下的配置管理。

單例的實現主要是通過以下兩個步驟

將該類的構造方法定義為私有方法,這樣其他處的**就無法通過呼叫該類的構造方法來例項化該類的物件,只有通過該類提供的靜態方法來得到該類的唯一例項;

在該類內提供乙個靜態方法,當我們呼叫這個方法時,如果類持有的引用不為空就返回這個引用,如果類保持的引用為空就建立該類的例項並將例項的引用賦予該類保持的引用。

舉乙個小例子,在我們的windows桌面上,我們開啟了乙個**站,當我們試圖再次開啟乙個新的**站時,windows系統並不會為你彈出乙個新的**站視窗。,也就是說在整個系統執行的過程中,系統只維護乙個**站的例項。這就是乙個典型的單例模式運用。

繼續說**站,我們在實際使用中並不存在需要同時開啟兩個**站視窗的必要性。假如我每次建立**站時都需要消耗大量的資源,而每個**站之間資源是共享的,那麼在沒有必要多次重複建立該例項的情況下,建立了多個例項,這樣做就會給系統造成不必要的負擔,造成資源浪費。

再舉乙個例子,**的計數器,一般也是採用單例模式實現,如果你存在多個計數器,每乙個使用者的訪問都重新整理計數器的值,這樣的話你的實計數的值是難以同步的。但是如果採用單例模式實現就不會存在這樣的問題,而且還可以避免執行緒安全問題。同樣多執行緒的執行緒池的設計一般也是採用單例模式,這是由於執行緒池需要方便對池中的執行緒進行控制

從上述的例子中我們可以總結出適合使用單例模式的場景和優缺點:  

適用場景:

優點

缺點

1.餓漢式

//

餓漢式單例

public

class

singleton1

//以自己例項為返回值的靜態的公有方法,靜態工廠方法

public

static

singleton1 getsingleton1()

}

我們知道,類載入的方式是按需載入,且載入一次。。因此,在上述單例類被載入時,就會例項化乙個物件並交給自己的引用,供系統使用;而且,由於這個類在整個生命週期中只會被載入一次,因此只會建立乙個例項,即能夠充分保證單例。

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

缺點:在類裝載的時候就完成例項化,沒有達到lazy loading的效果。如果從始至終從未使用過這個例項,則會造成記憶體的浪費。

2.懶漢式

//

懶漢式單例

public

class

singleton2

//以自己例項為返回值的靜態的公有方法,靜態工廠方法

public

static

singleton2 getsingleton2()

return

singleton2;}}

我們從懶漢式單例可以看到,單例例項被延遲載入,即只有在真正使用的時候才會例項化乙個物件並交給自己的引用。

這種寫法起到了lazy loading的效果,但是只能在單執行緒下使用。如果在多執行緒下,乙個執行緒進入了if (singleton == null)判斷語句塊,還未來得及往下執行,另乙個執行緒也通過了這個判斷語句,這時便會產生多個例項。所以在多執行緒環境下不可使用這種方式。

3.雙重加鎖機制

public

class

singleton

public

static

singleton getinstance()}}

return

instance;}}

double-check概念對於多執行緒開發者來說不會陌生,如**中所示,我們進行了兩次if (singleton == null)檢查,這樣就可以保證執行緒安全了。這樣,例項化**只用執行一次,後面再次訪問時,判斷if (singleton == null),直接return例項化物件。

使用雙重檢測同步延遲載入去建立單例的做法是乙個非常優秀的做法,其不但保證了單例,而且切實提高了程式執行效率

優點:執行緒安全;延遲載入;效率較高。

4.靜態初始化

//

阻止發生派生,而派生可能會增加例項

public

sealed

class

singleton

public

static

singleton getinstance()

}

在實際應用中,c#與公共語言執行庫也提供了一種「靜態初始化」方法,這種方法不需要開發人員顯式地編寫執行緒安全**,即可解決多執行緒環境下它是不安全的問題。

當然,單例模式的實現方法還有很多。但是,這四種是比較經典的實現,也是我們應該掌握的幾種實現方式。

從這四種實現中,我們可以總結出,要想實現效率高的執行緒安全的單例,我們必須注意以下兩點:

深入理解單例模式的雙重加鎖模式

本文從單例模式的一般實現方式開始說起,逐步深入到雙重加鎖實現。首先介紹一下最簡單的單例模式 餓漢模式,這種方式在單例類被載入的時候例項化。實現如下 1 public class singleton 7 8 private singleton 10 11 public static singleton...

理解設計模式 單例模式

定義 確保要建立的類只有乙個例項 對於頻繁建立的物件,可以省略其建立時間,同時可以減輕gc的壓力 避免對共享資源的多重占用 使用場景 單例模式寫法很多,這裡列舉以下三種 1 最簡單的寫法 使用列舉物件public enum singletonenum使用列舉還可以避免反射獲取類的私有構造方法從而建立...

設計模式 理解單例設計模式

設計模式分類 結構型行為型 建立型 單例模式屬於建立型設計模式 單例模式主要使用在 日誌記錄 將多項服務的日誌資訊按照順序儲存到乙個特定日誌檔案 資料庫操作 使用乙個資料庫物件進行操作,保證資料的一致性 印表機後台處理程式 以及其他程式 該程式執行過程中 只能生成乙個例項 避免對同一資源產生相互衝突...