国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C#設計模式之單例模式

這篇具有很好參考價值的文章主要介紹了C#設計模式之單例模式。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

介紹

單例模式(Singleton)保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。

單例模式的結(jié)構(gòu)圖如下所示:

使用單例模式的原因

對一些類來說,只有一個實例是很重要的。如何才能保證一個類只有一個實例并且這個實例易于被訪問呢?

基于程序員之間的約定或是利用全局變量嗎?

雖然這樣或許也可以實現(xiàn),但是單例模式確是更好的做法。因為僅僅靠約定或是全局變量,如果重新new一個對象,還是可以創(chuàng)建新的實例。

經(jīng)典的單例模式

現(xiàn)在我們先來看看經(jīng)典的單例模式寫法:

 ?public class Singleton
{
? ? ?private static Singleton? _instance;
? ? ?private Singleton() { }
? ? ?public static Singleton GetInstance()
? ? {
? ? ? ? ?if(_instance == null)
? ? ? ? ? ?_instance = new Singleton();
? ? ? ? return _instance;
? ? }
}
private static Singleton? _instance;

聲明了一個靜態(tài)的類變量,靜態(tài)類變量在類的所有實例之間共享, 與類關聯(lián)而不是與類的實例關聯(lián),它在整個應用程序域中只有一個實例。

 private Singleton() { }

私有的構(gòu)造函數(shù),這使得我們無法通過:

 Singleton Singleton = new Singleton();

這種寫法來創(chuàng)建它的實例,這樣寫會報錯,如下所示:

 ?public static Singleton GetInstance()
? ? {
? ? ? ? ?if(_instance == null)
? ? ? ? ? ?_instance = new Singleton();
? ? ? ? return _instance;
? ? }

該方法是獲得本類實例的唯一全局訪問點。

如果實例不存在,在類的內(nèi)部可以通過new操作符來獲取一個實例,否則返回已有的實例。

 internal class Program
{
? ? static void Main(string[] args)
? ? { ? ? ? ?
? ? ? ? Singleton singleton1 = Singleton.GetInstance();
? ? ? ? Singleton singleton2 = Singleton.GetInstance();
? ? ? ? if (singleton1 == singleton2)
? ? ? ? ? ? Console.WriteLine("兩個對象是相同的實例");
? ? }
}

比較兩個對象看看它們是不是同一個實例,運行結(jié)果如下所示:

多線程下的單例模式

上述代碼在多線程情況下會存在問題,如果有多個線程同時訪問Singleton類調(diào)用GetInstance方法,會有可能造成創(chuàng)建多個實例。

查看以下代碼:

internal class Program
{
? ?static void Main(string[] args)
? { ? ? ? ?
? ? ? ?// 創(chuàng)建并啟動兩個任務
? ? ? ?Task task1 = Task.Factory.StartNew(Method1);
? ? ? ?Task task2 = Task.Factory.StartNew(Method2);
? ? ? ?Task.WaitAll(task1, task2); ? ? ? ?
? ? ? ?Console.WriteLine("所有任務完成");
? ? ? ?void Method1()
? ? ? {
? ? ? ? ? ?Console.WriteLine("Task 1 is running.");
? ? ? ? ? ?Task.Delay(1000).Wait();
? ? ? ? ? ?Singleton singleton1 = Singleton.GetInstance();
? ? ? ? ? ?Console.WriteLine(singleton1.GetHashCode());
? ? ? }
?
? ? ? ? void Method2()
? ? ? { ? ? ? ?
? ? ? ? ? ?Console.WriteLine("Task 2 is running.");
? ? ? ? ? ?Task.Delay(1000).Wait();
? ? ? ? ? ?Singleton singleton2 = Singleton.GetInstance();
? ? ? ? ? ?Console.WriteLine(singleton2.GetHashCode());
? ? ? }
? }
}

運行結(jié)果如下所示:

兩個對象的哈希碼不同,在C#中,每個對象都有一個GetHashCode方法,該方法返回該對象的哈希碼。默認情況下,GetHashCode方法是根據(jù)對象的內(nèi)存地址生成的,因此兩個不同的實例在內(nèi)存中有不同的地址,它們的哈希碼通常也是不同的。然而,這并不是說哈希碼不同就一定表示兩個對象是不同的。因為哈希碼是一個有限的整數(shù),存在哈希沖突的可能性。兩個不同的對象可能具有相同的哈希碼,這被稱為哈希沖突。因此,不能僅僅通過比較哈希碼就斷定兩個對象是相同的還是不同的。

但是我們在這里我們可以這樣進行簡單的判斷。

那么該如何解決這個問題呢?

使用lock

C#中可以使用lock來解決。 lock 語句可確保在任何時候最多只有一個線程執(zhí)行其主體。

可以這樣進行改寫:

 public class Singleton
{
? ? private static Singleton? _instance;
? ? private static readonly object _syncRoot = new object();
? ? private Singleton() { }
? ? public static Singleton GetInstance()
? ? {
? ? ? ? lock (_syncRoot)
? ? ? ? {
? ? ? ? ? ? if (_instance == null)
? ? ? ? ? ? ? ? _instance = new Singleton();
? ? ? ? }
? ? ? ?return _instance;
? ? }
}
 private static readonly object _syncRoot = new object();

程序運行時創(chuàng)建一個靜態(tài)只讀的輔助對象。

 ?public static Singleton GetInstance()
? ? {
? ? ? ? lock (_syncRoot)
? ? ? ? {
? ? ? ? ? ? if (_instance == null)
? ? ? ? ? ? ? ? _instance = new Singleton();
? ? ? ? }
? ? ? ?return _instance;
? ? }

lock語句確保在任何時候最多只有一個線程執(zhí)行其主體。

現(xiàn)在再來看看運行結(jié)果:

雙重鎖定

現(xiàn)在兩個對象的哈希碼一樣了,在這里我們可以簡單的認為是同一個實例了。

但是每次都要執(zhí)行l(wèi)ock語句會影響性能,還需要改進:

 ?public class Singleton
{
? ? ?private static Singleton? _instance;
? ? ?private static readonly object _syncRoot = new object();
? ? ?private Singleton() { }
? ? ?public static Singleton GetInstance()
? ? {
? ? ? ? ?if (_instance == null)
? ? ? ? {
? ? ? ? ? ? ?lock (_syncRoot)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ?if(_instance == null)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ?_instance = new Singleton();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? } ? ? ? ? ? ? ?
? ? ? ? return _instance;
? ? }
}

這樣子當存在_instance時,直接返回,沒有執(zhí)行l(wèi)ock語句。為什么執(zhí)行兩次if(_instance == null)判斷是因為當_instance == null時,如果同時有兩個線程調(diào)用GetInstance方法,它們都可以通過第一次判斷,由于lock的機制,這兩個線程只有一個進去,另一個在外排隊等候,必須等上一個進入并且退出之后,第二個線程才能進入,而此時如果沒有第二層的判斷,那么第一個線程與第二個線程都會創(chuàng)建新的實例,而添加了這個判斷之后,第一個線程創(chuàng)建了實例,_instanc就不為空,第二個線程就無法創(chuàng)建新的實例了。

現(xiàn)在再來看看運行結(jié)果:

靜態(tài)初始化

其實在實際應用中,C#也可以采用靜態(tài)初始化的方法,這種方法不需要開發(fā)人員顯式地編寫線程安全代碼,即可解決多線程環(huán)境下不安全的問題。

 public sealed class Singleton
{
? ? private static readonly Singleton _instance = new Singleton(); ? ?
? ? private Singleton() { }
? ? public static Singleton GetInstance()
? ? { ? ? ? ?
? ? ? return _instance;
? ? }
}

使用sealed關鍵字表示是密封類,阻止發(fā)生派生,因為派生可能會增加實例。

 private static readonly Singleton _instance = new Singleton(); ? ? 

在第一次引用類的任何成員時創(chuàng)建實例,公共語言運行時負責處理變量初始化。

現(xiàn)在再來看看運行結(jié)果:

由于這種靜態(tài)初始化的方式是在自己被加載時就將自己實例化,所以被形象地稱之為餓漢單例類,原先的單例模式的處理方式是要在第一次被引用時,才會將自己實例化,所以就被稱為懶漢單例類

總結(jié)

本文介紹了在C#中如何使用單例模式,并介紹了在多線程模式下單例模式可能存在的問題及其解決方法,希望對你有所幫助。

參考

1、《Head First 設計模式(中文版)》

2、《大話設計模式》

3、《設計模式:可復用面向?qū)ο筌浖幕A》文章來源地址http://www.zghlxwxcb.cn/news/detail-777750.html

到了這里,關于C#設計模式之單例模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Java設計模式之單例模式

    Java設計模式之單例模式

    定義:保證一個類僅有一個實例,并提供一個全局訪問點 類型:創(chuàng)建型 想確保任何情況下都絕對只有一個實例 例如:線程池,數(shù)據(jù)庫連接池一般都為單例模式 單例模式優(yōu)點 在內(nèi)存中只有一個實例,減少內(nèi)存開銷 可以避免對資源的多重占用 設置全局訪問點,嚴格控制訪問

    2024年02月02日
    瀏覽(56)
  • 設計模式之單例模式(懶漢, 餓漢)

    設計模式之單例模式(懶漢, 餓漢)

    單例模式是一種常用的軟件設計模式, 該模式的主要目的是確保某一個類在內(nèi)存中只能有一個實例對象, 通過單例模式的方法創(chuàng)建的類在當前進程中只有一個實例對象. 常見的單例模式有兩種: 餓漢式, 這里的 “餓” 意義表述不夠清晰, 用 “急” 來表述意義更加容易聯(lián)想一些

    2024年02月22日
    瀏覽(20)
  • C#--設計模式之單例模式

    C#--設計模式之單例模式

    單例模式大概是所有設計模式中最簡單的一種,如果在面試時被問及熟悉哪些設計模式,你可能第一個答的就是單例模式。 單例模式的實現(xiàn)分為兩種: 餓漢式:在靜態(tài)構(gòu)造函數(shù)執(zhí)行時就立即實例化。 懶漢式:在程序執(zhí)行過程中第一次需要時再實例化。 兩者有各自適用的場景

    2024年02月14日
    瀏覽(12)
  • 淺談設計模式之單例模式

    淺談設計模式之單例模式

    單例模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。單例模式指的是 單一的一個類 ,該類負責創(chuàng)建自己的對象,并且保證該 對象唯一 。該類提供了一種訪問其唯一對象的方法,外部需要調(diào)用該類的對象可以通過方法獲取,不需要實例化類的對象。 關鍵點: 單例

    2024年02月16日
    瀏覽(20)
  • 萬字解析設計模式之單例模式

    萬字解析設計模式之單例模式

    單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。 這種模式涉及到一個 單一 的類,該類負責創(chuàng)建自己的對象,同時確保 只有單個對象被創(chuàng)建 。這個類提供了一種訪問其唯一的對象的方式,

    2024年02月08日
    瀏覽(28)
  • 【Java 設計模式】創(chuàng)建型之單例模式

    【Java 設計模式】創(chuàng)建型之單例模式

    在軟件開發(fā)中,單例模式是一種常見的設計模式, 它確保一個類只有一個實例,并提供一個全局訪問點 。單例模式在需要控制某些資源,如數(shù)據(jù)庫連接池、線程池等共享資源的情況下非常有用。在本文中,我們將介紹 Java 設計模式中的單例模式,了解其實現(xiàn)方式、使用場景

    2024年01月18日
    瀏覽(26)
  • 跟著GPT學設計模式之單例模式

    單例設計模式(Singleton Design Pattern)一個類只允許創(chuàng)建一個對象(或者實例),那這個類就是一個單例類,這種設計模式就叫作單例設計模式,簡稱單例模式。 單例有幾種經(jīng)典的實現(xiàn)方式,它們分別是:餓漢式、懶漢式、雙重檢測、靜態(tài)內(nèi)部類、枚舉。 處理資源訪問沖突,

    2024年02月05日
    瀏覽(28)
  • C++設計模式創(chuàng)建型之單例模式

    一、概述 ? ? ? ? 單例模式也稱單態(tài)模式,是一種創(chuàng)建型模式,用于創(chuàng)建只能產(chǎn)生一個對象實例的類。例如,項目中只存在一個聲音管理系統(tǒng)、一個配置系統(tǒng)、一個文件管理系統(tǒng)、一個日志系統(tǒng)等,甚至如果吧整個Windows操作系統(tǒng)看成一個項目,那么其中只存在一個任務管理

    2024年02月14日
    瀏覽(29)
  • Gof23設計模式之單例模式(完整)

    單例模式(Singleton pattern)是Java中最簡單的設計模式之一。這種設計模式屬于創(chuàng)建型模型,它提供了一種創(chuàng)建對象的最佳方式。 這種模式涉及到一個單一的類,該類負責創(chuàng)建自己的對象,同時確保只有單個對象被創(chuàng)建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪

    2024年02月10日
    瀏覽(26)
  • 深入理解設計模式-創(chuàng)建型之單例模式

    如果有些數(shù)據(jù)在系統(tǒng)中應該且只能保存一份,那就應該設計為單例類。 如:配置類:在系統(tǒng)中,我們只有一個配置文件,當配置文件被加載到內(nèi)存之后,應該被映射為一個唯一的【配置實例】,此時就可以使用單例,當然也可以不用。 全局計數(shù)器:我們使用一個全局的計數(shù)

    2024年02月12日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包