第5章分布式系統模式 Singleton

2022-05-05 11:18:12 字數 3924 閱讀 1406

在某些情況下,特定型別的資料需要提供給應用程式中的其他所有物件使用。在大多數情況下,這種型別的資料在系統中還是唯一的。例如,使用者介面只能有乙個所有應用程式必須訪問的滑鼠指標。同樣,企業解決方案可能用單閘道器物件作為介面來管理與特定舊系統的連線。

以下因素影響這種情況中的系統,在考慮上述問題的解決方案時必須協調這些影響因素:

singleton 通過下列方法提供唯一的全域性例項:

圖 1 顯示了該模式的靜態結構。uml 類圖表非常簡單,這是因為singleton 由乙個簡單類組成,而該類包含了對其自身的單個例項的引用。

圖 1:singleton

結構圖 1 顯示,singleton類包含了公用類作用範圍(靜態)屬性,該屬性會返回對singleton類的單個例項的引用。(uml 中的下劃線表示類作用範圍屬性。)另外,右上角的數字 1 表示任何時候在系統中該類只能有乙個例項。因為singleton的預設建構函式是私有的,因此系統中的任何其他物件都必須通過instance屬性才能訪問singleton物件。

通常將singleton 模式歸類為慣用語,而不是模式,這是因為該解決方案主要取決於所用程式語言的功能(例如類方法和靜態初始值)。正如該模式集合所做的那樣,將抽象的概念與特定的實現分隔開來可能會使singleton 實現看起來非常簡單。

singleton 會導致下列優缺點:

優點

缺點

要在c#中構建應用程式。您需要只有乙個例項的類,並且需要提供乙個用於訪問例項的全域性訪問點。您希望確保您的解決方案高效,並且能夠利用microsoft? .net公共語言執行庫功能。您可能還希望確保解決方案是執行緒安全的。

儘管 singleton

是一種相對簡單的模式,但是存在與具體實現有關的不同權衡因素和選項。下面是一組實現策略,及其優缺點的討論。

singleton

singleton 設計模式的下列實現採用了 design patterns: elements of reusable object-oriented software[gamma95]中所描述的解決方案,但對它進行了修改,以便利用c#中可用的語言功能,如屬性:

using system;
public class singleton
public static singleton instance
return instance;
}
}
}
該實現主要有兩個優點:

但是,這種實現的主要缺點是在多執行緒環境下它是不安全的。如果執行過程的不同執行緒同時進入instance屬性方法,那麼可能會建立多個singleton物件例項。每個執行緒都會執行下列語句,並決定必須建立新的例項:

if (instance == null)
解決此問題的方法有很多。一種方法是使用被稱為 double-check locking[lea99]的技術。而 c# 與公共語言執行庫也提供了一種"靜態初始化"方法,這種方法不需要開發人員顯式地編寫執行緒安全**,即可解決這些問題。

靜態初始化

one of the reasons design patterns[gamma95]避免使用靜態初始化的原因之一是,c++規範在靜態變數的初始化順序方面留下了一些多義性。幸運的是,.net framework通過其變數初始化處理方法解決了這種多義性:

public sealed class singleton
public static singleton instance
}
}
在此策略中,將在第一次引用類的任何成員時建立例項。公共語言執行庫負責處理變數初始化。該類標記為sealed以阻止發生派生,而派生可能會增加例項。有關將類標記為sealed的利與弊的討論,請參閱[sells03]。此外,變數標記為readonly,這意味著只能在靜態初始化期間(此處顯示的示例)或在類建構函式中分配變數。

該實現與前面的示例類似,不同之處在於它依賴公共語言執行庫來初始化變數。它仍然可以用來解決 singleton 模式試**決的兩個基本問題:全域性訪問和例項化控制。公共靜態屬性為訪問例項提供了乙個全域性訪問點。此外,由於建構函式是私有的,因此不能在類本身以外例項化singleton類;因此,變數引用的是可以在系統中存在的唯一的例項。

由於singleton例項被私有靜態成員變數引用,因此在類首次被對instance屬性的呼叫所引用之前,不會發生例項化。因此,與 design patterns 形式的 singleton 一樣,該解決方案實現了懶例項化屬性的一種形式。

這種方法唯一的潛在缺點是,您對例項化機制的控制權較少。在 design patterns 形式中,您能夠在例項化之前使用非預設的建構函式或執行其他任務。由於在此解決方案中由.net framework負責執行初始化,因此您沒有這些選項。在大多數情況下,靜態初始化是在.net中實現 singleton 的首選方法。

多執行緒 singleton

靜 態初始化適合於大多數情形。如果您的應用程式必須延遲例項化、在例項化之前使用非預設的建構函式或執行其他任務、並且工作在多執行緒環境中,那麼您需要另一 種解決方案。但是,在一些情況下,您無法像在"靜態初始化"示例中那樣依賴公共語言執行庫來確保執行緒的安全性。在這種情況下,必須使用特定的語言功能來確 保在存在多執行緒的情況下僅建立乙個物件例項。更常見的解決方案之一是使用 double-check locking[lea99]技術來阻止不同的執行緒同時建立singleton的新例項。

下面的實現僅允許乙個執行緒在尚未建立singleton例項的情況下進入關鍵區域(該區域由lock塊標識)。

using system;
public sealed class singleton
public static singleton instance
}
return instance;
}
}
}
此方法確保了僅在需要例項時才會建立僅乙個例項。此外,變數被宣告為volatile,以確保只有在例項變數分配完成後才能訪問例項變數。最後,此方法使用syncroot例項來進行鎖定(而不是鎖定型別本身),以避免發生死鎖。

double-check locking方法解決了執行緒併發問題,同時避免在每個instance屬性方法的呼叫中都出現獨佔鎖定。它還允許您將例項化延遲到第一次訪問物件時發生。實際上,應用程式很少需要這種型別的實現。大多數情況下,靜態初始化方法已經夠用。

c#中實現singleton具有下列優缺點:

優點

缺點

如果您的多執行緒應用程式需要進行顯式初始化,那麼必須採取措施以避免執行緒問題。

第11章 分布式Cache

1.單層的分布式cache memcached 使用key 和value 的簡單資料格式,把key 和value 的對應關係使用hash 表的形式存放在記憶體中,並使用lru 演算法把過期的資料從記憶體中移出。全世界有很多 來使用這個專案來構建大負載 來分擔資料庫的壓力。2.多層的分布式cache ...

分布式系統 第2課

第一題 用tcpdump tshark等工具來來分析arp請求報文和應答報文,對照截獲的資料,做出arp請求應答的邏輯分析,建議本機安裝虛擬機器來進行測試和實踐。假設主機a和b在同乙個網段,主機a要向主機b傳送資訊,通過arp將ip位址解析為mac位址的過程如下 1 主機a首先檢視自己的arp表,確...

分布式5 zookeeper分布式

一 為什麼需要zookeeper 大部分分布式應用需要乙個主控 協調器或控制器來管理物理分布的子程序 如資源 任務分配等 大部分應用需要開發私有的協調程式,缺乏乙個通用的機制 協調程式的反覆編寫浪費,且難以形成通用 伸縮性好的協調器 zookeeper可以提供通用的分布式鎖服務,用以協調分布式應用,...