翻 C 中單例項模式的實現

2021-08-26 20:43:45 字數 1587 閱讀 9937

[toc]

單例項模式是軟體工程中最知名的模式之一。本質上講,單例項只允許本身建立單個例項的類,並且通常會給出乙個訪問該例項的簡單方法。通常情況下,單例模式在建立例項時,不允許指定任何引數。否則,對例項進行第二次請求,但引數不同,就會產生問題(如果所有訪問同一單例項的請求都是同樣的引數,則工程模式更為合適)。本文只討論不需要引數的情況。典型的單例項模式是例項被懶洋洋的建立,即需要例項時例項才被建立。

在c#中,實現單例項模式有多種方法。我將一步步介紹更加優雅的方法。從最常見的不安全執行緒的版本開始,一直到完全惰性載入,執行緒安全,簡單且高效能的版本。

所有這些實現都有以下幾個共同點:

1. 私有且沒有引數的單一構造器。這樣可以防止其他類例項化它。沒有子類(不可以被繼承),如果可以被子類化一次,那麼就可以被子類化兩次,如果每乙個子類都可以建立乙個例項,那麼這個模式就沒有了意義。如果需要乙個基型別的單個例項,則可以使用工廠模式。但直到執行時才知道確切的型別。

2. 這個類是密封的(sealed),嚴格來說,並不是必須的。但由於上邊的觀點,加上sealed可能有助於jit進行優化。

3. 如果需要保持對單個建立例項的應用,需要用乙個靜態變數。

4. 乙個公共靜態方法,用於獲取對單個建立例項的引用,必要時建立乙個例項。

請注意,所有這些實現都使用公共靜態屬性例項作為訪問例項的方法。在所有情況下,該屬性都可以很容易地轉換成乙個方法,對執行緒安全或效能沒有影響。

// bad code! do not use!

public

sealed

class singleton

public

static singleton instance

return instance;}}

}

如前邊所述,上述是執行緒不安全的。若instance==null為真,那麼兩個不同執行緒都可以建立違反單例項模式的例項。請注意,實際上例項可能已經在表示式被求值之前建立了,但是記憶體模型並不能保證例項的新值將被其他執行緒看到,除非已經傳遞了適當的記憶體屏障。

public

sealed

class singleton

public

static singleton instance

return instance;}}

}}

這個實現是執行緒安全的。執行緒取出乙個共享物件上的鎖,然後在建立例項之前檢查該例項是否已被建立。鎖負責記憶體屏障的問題(所有讀取鎖確保發生邏輯鎖獲取後,和釋放鎖之前確保所有的寫都是邏輯上發布),確保一次只有乙個執行緒將建立乙個例項(因為只有乙個執行緒可以在這部分的**時,第二個執行緒進入它的時候,第乙個執行緒將建立例項,所以表示式將評估為false)。不幸的是,每當例項被請求時,效能就會受到影響。

請注意,與其將typeof(單件)鎖定為該實現的某些版本,我鎖定了乙個靜態變數的值,該變數是該類的私有變數。鎖定其他類可以訪問和鎖定的物件(比如型別)可能會導致效能問題,甚至是死鎖。這是我的一般風格偏好——只要可能,只鎖定為鎖定目的而專門建立的物件,或者為了特定的目的而鎖定它們的文件(例如等待/脈衝佇列)。通常這樣的物件應該是他們所使用的類的私有。這有助於使編寫執行緒安全的應用程式變得更加容易。

單例項設計模式的實現

單例項設可能是使用最廣泛的設計模式。其思想意圖是保證乙個類只有乙個例項,並且提供類物件的全程訪問。單例項物件應用的範圍很廣 如gui應用必須是單滑鼠,modem的聯接需要一條且只需要一條 線,作業系統只能有乙個視窗管理器,一台pc連乙個鍵盤。本文將討論如何用c 實現單例項模式,並解釋如何優化單執行緒...

C 中實現單例模式

單例模式是軟體工程中廣為人知的設計模式。單例模式就是指乙個永遠只能例項化一次。使用的方式是呼叫類裡建立的靜態方法。通常來說,單例模式建立的類,都是不帶形參的 原因就是當建立多個例項的時候,如果引數不同的話 比如2個不同的過載建構函式 那麼就會造成一些不必要的問題 如果相同的例項要被建立而且他們使用相...

C 例項 單例模式

昨天晚上,我的老師 算是我的親戚 給了我一段 讓我看看。現copy如下 1 citysingleton.cs檔案 using system using system.data using system.configuration using system.web using system.web.s...