最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c#設(shè)計(jì)模式之單例模式的實(shí)現(xiàn)方式

 更新時(shí)間:2019年11月02日 15:30:59   作者:猴子哥  
這篇文章主要給大家介紹了關(guān)于c#設(shè)計(jì)模式之單例模式的實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用c#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

場(chǎng)景描述

單例模式對(duì)于我們來(lái)說(shuō)一點(diǎn)也不模式,是一個(gè)常見(jiàn)的名稱(chēng),單例模式在程序中的實(shí)際效果就是:確保一個(gè)程序中只有一個(gè)實(shí)例,并提供一個(gè)全局訪(fǎng)問(wèn)點(diǎn),節(jié)省系統(tǒng)資源

單例模式無(wú)論是在實(shí)際開(kāi)發(fā)中還是在軟件應(yīng)用中比較常見(jiàn),比如,windows系統(tǒng)的任務(wù)管理器、IIS的HttpApplication、實(shí)際項(xiàng)目中的日志組件等等

實(shí)現(xiàn)方式

單例模式為了實(shí)現(xiàn)一個(gè)實(shí)例,那么只有不把實(shí)例創(chuàng)建暴露出去,只通過(guò)類(lèi)本身來(lái)創(chuàng)建實(shí)例,為了實(shí)現(xiàn)效果,需要定義一個(gè)私有構(gòu)造函數(shù)

單例模式實(shí)現(xiàn)方式有:餓漢式、懶漢式、雙重驗(yàn)證式、靜態(tài)內(nèi)部類(lèi)

下面分別對(duì)每一種實(shí)現(xiàn)方式做一個(gè)簡(jiǎn)單的實(shí)例,以及其優(yōu)缺點(diǎn)

餓漢式

/// <summary>
 /// 創(chuàng)建一個(gè) Singleton 類(lèi)(餓漢式)
 /// 這種方式比較常用,但容易產(chǎn)生垃圾對(duì)象。
 ///優(yōu)點(diǎn):沒(méi)有加鎖,執(zhí)行效率會(huì)提高。
 ///缺點(diǎn):類(lèi)加載時(shí)就初始化,浪費(fèi)內(nèi)存。
 ///它基于 classloder 機(jī)制避免了多線(xiàn)程的同步問(wèn)題,不過(guò),instance 在類(lèi)裝載時(shí)就實(shí)例化,
 ///雖然導(dǎo)致類(lèi)裝載的原因有很多種,在單例模式中大多數(shù)都是調(diào)用 getInstance 方法,
 ///但是也不能確定有其他的方式(或者其他的靜態(tài)方法)導(dǎo)致類(lèi)裝載,這時(shí)候初始化 instance 顯然沒(méi)有達(dá)到 lazy loading 的效果。
 /// </summary>
 public class SingleObject
 {
  //創(chuàng)建 SingleObject 的一個(gè)對(duì)象
  private static SingleObject instance = new SingleObject();

  //讓構(gòu)造函數(shù)為 private,這樣該類(lèi)就不會(huì)被實(shí)例化
  private SingleObject() {
   Console.WriteLine("我被創(chuàng)建了.餓漢式");
  }

  //獲取唯一可用的對(duì)象
  public static SingleObject GetInstance()
  {
   return instance;
  }

  public void ShowMessage()
  {
   Console.WriteLine("Hello World.餓漢式");
  }
 }

懶漢式

/// <summary>
 /// 創(chuàng)建一個(gè) Singleton 類(lèi)(懶漢式)
 /// 這種方式具備很好的 lazy loading,能夠在多線(xiàn)程中很好的工作,但是,效率很低,99% 情況下不需要同步。
 /// 優(yōu)點(diǎn):第一次調(diào)用才初始化,避免內(nèi)存浪費(fèi)。
 /// 缺點(diǎn):懶漢式在單個(gè)線(xiàn)程中沒(méi)有問(wèn)題,但多個(gè)線(xiàn)程同事訪(fǎng)問(wèn)的時(shí)候就可能同事創(chuàng)建多個(gè)實(shí)例,而且這多個(gè)實(shí)例不是同一個(gè)對(duì)象。
 /// </summary>
 public class SingleObject1
 {
  //創(chuàng)建 SingleObject 的一個(gè)對(duì)象
  private static SingleObject1 instance;

  //讓構(gòu)造函數(shù)為 private,這樣該類(lèi)就不會(huì)被實(shí)例化
  private SingleObject1() { }

  //獲取唯一可用的對(duì)象
  public static SingleObject1 GetInstance()
  {
   if (instance == null)
   {
    instance = new SingleObject1();
    Console.WriteLine("我被創(chuàng)建了.懶漢式");
   }
   return instance;
  }

  public void ShowMessage()
  {
   Console.WriteLine("Hello World.懶漢式");
  }
 }

雙重驗(yàn)證式

/// <summary>
 /// 創(chuàng)建一個(gè) Singleton 類(lèi)(雙重驗(yàn)證)
 /// 這種方式具備很好的 lazy loading,能夠在多線(xiàn)程中很好的工作,但是,效率很低,99% 情況下不需要同步。
 /// 優(yōu)點(diǎn):第一次調(diào)用才初始化,避免內(nèi)存浪費(fèi),線(xiàn)程安全。
 /// 缺點(diǎn):必須加鎖 synchronized 才能保證單例,但加鎖會(huì)影響效率。
 /// </summary>
 public class SingleObject2
 {
  //創(chuàng)建 SingleObject 的一個(gè)對(duì)象
  private static SingleObject2 instance;

  // 定義一個(gè)標(biāo)識(shí)確保線(xiàn)程同步
  private static readonly object locker = new object();


  //讓構(gòu)造函數(shù)為 private,這樣該類(lèi)就不會(huì)被實(shí)例化
  private SingleObject2() { }

  //獲取唯一可用的對(duì)象
  public static SingleObject2 GetInstance()
  {
   //// 如果為空,那么就加鎖,創(chuàng)建實(shí)例
   if (instance == null)
   {
    lock (locker)
    {
     //// 枷鎖成功后,在做一次非空判斷,避免在加鎖期間以創(chuàng)建了實(shí)例而導(dǎo)致重復(fù)創(chuàng)建
     if (instance == null)
     {
      instance = new SingleObject2();
      Console.WriteLine("我被創(chuàng)建了.雙重驗(yàn)證");
     }
    }
   }
   return instance;
  }

  public void ShowMessage()
  {
   Console.WriteLine("Hello World.雙重驗(yàn)證");
  }
 }

靜態(tài)內(nèi)部類(lèi)

/// <summary>
 /// 創(chuàng)建一個(gè) Singleton 類(lèi)(靜態(tài)內(nèi)部類(lèi)) 
 /// 這種方式不用加鎖,在效率上和內(nèi)存使用上都比較優(yōu)秀
 /// 克服了餓漢模式的不足餓漢模式執(zhí)行效率高,由于在類(lèi)加載的時(shí)候初始化導(dǎo)致內(nèi)存浪費(fèi)
 /// </summary>
 public class SingletonStatic
 {
  /// <summary>
  /// 內(nèi)部類(lèi)
  /// </summary>
  public class SingletonStaticInner
  {
   /// <summary>
   /// 當(dāng)一個(gè)類(lèi)有靜態(tài)構(gòu)造函數(shù)時(shí),它的靜態(tài)成員變量不會(huì)被beforefieldinit修飾
   /// 就會(huì)確保在被引用的時(shí)候才會(huì)實(shí)例化,而不是程序啟動(dòng)的時(shí)候?qū)嵗?
   /// </summary>
   static SingletonStaticInner() { }

   /// <summary>
   /// 實(shí)例化
   /// </summary>
   internal static SingletonStatic singletonStatic = new SingletonStatic();
  }

  /// <summary>
  /// 私有構(gòu)造函數(shù)
  /// </summary>
  private SingletonStatic() {
   Console.WriteLine("我被創(chuàng)建了.靜態(tài)內(nèi)部類(lèi)");
  }

  /// <summary>
  /// 獲取實(shí)例
  /// </summary>
  /// <returns></returns>
  public static SingletonStatic GetInstance()
  {
   return SingletonStaticInner.singletonStatic;
  }

  public void ShowMessage()
  {
   Console.WriteLine("Hello World.靜態(tài)內(nèi)部類(lèi)");
  }
 }

每一種創(chuàng)建方式測(cè)試

創(chuàng)建一個(gè)控制臺(tái)程序,通過(guò)多線(xiàn)程對(duì)每一種實(shí)現(xiàn)方式使用,查看其實(shí)例次數(shù)分析:

/*
 介紹
意圖:保證一個(gè)類(lèi)僅有一個(gè)實(shí)例,并提供一個(gè)訪(fǎng)問(wèn)它的全局訪(fǎng)問(wèn)點(diǎn)。
主要解決:一個(gè)全局使用的類(lèi)頻繁地創(chuàng)建與銷(xiāo)毀。
何時(shí)使用:當(dāng)您想控制實(shí)例數(shù)目,節(jié)省系統(tǒng)資源的時(shí)候。
如何解決:判斷系統(tǒng)是否已經(jīng)有這個(gè)單例,如果有則返回,如果沒(méi)有則創(chuàng)建。
關(guān)鍵代碼:構(gòu)造函數(shù)是私有的。
應(yīng)用實(shí)例:
典型的已有應(yīng)用:
1、windows的任務(wù)管理器等
2、IIS的HttpApplication,所有的HttpModule都共享一個(gè)HttpApplication實(shí)例
在項(xiàng)目中的實(shí)際使用場(chǎng)景:
1、日志組件
2、多線(xiàn)程線(xiàn)程池管理
3、網(wǎng)站計(jì)數(shù)器
4、配置文件管理
  */
 
class Program
 {
  static void Main(string[] args)
  {
   TaskFactory taskFactory = new TaskFactory();
   List<Task> taskList = new List<Task>();

   //// 測(cè)試--餓漢式 
   for (int i = 0; i < 5; i++)
   {
    taskList.Add(taskFactory.StartNew(() =>
    {
     SingleObject.GetInstance();
    }));
   }

   //// 測(cè)試--懶漢式 
   for (int i = 0; i < 5; i++)
   {
    taskList.Add(taskFactory.StartNew(() =>
    {
     SingleObject1.GetInstance();
    }));
   }

   //// 測(cè)試--雙重驗(yàn)證 
   for (int i = 0; i < 5; i++)
   {
    taskList.Add(taskFactory.StartNew(() =>
    {
     SingleObject2.GetInstance();
    }));
   }

   //// 測(cè)試--靜態(tài)內(nèi)部類(lèi) 
   for (int i = 0; i < 5; i++)
   {
    taskList.Add(taskFactory.StartNew(() =>
    {
     SingletonStatic.GetInstance();
    }));
   }

   Console.ReadLine();
  }
 }

運(yùn)行結(jié)果:

  

通過(guò)結(jié)果可以看出:懶漢式實(shí)際創(chuàng)建了2個(gè)實(shí)例,所以在多線(xiàn)程中,懶漢式有線(xiàn)程不安全問(wèn)題

總結(jié)

根據(jù)單例模式是每一種實(shí)現(xiàn)方式對(duì)比分析,在實(shí)際使用過(guò)程中:

如果是單線(xiàn)程應(yīng)用環(huán)境,建議可以采用懶漢模

如果是多線(xiàn)程應(yīng)用環(huán)境,建議采用靜態(tài)內(nèi)部類(lèi)方式

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • 深入HTTP head的使用詳解

    深入HTTP head的使用詳解

    本篇文章是對(duì)HTTP head的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 帶著問(wèn)題讀CLR via C#(筆記一)CLR的執(zhí)行模型

    帶著問(wèn)題讀CLR via C#(筆記一)CLR的執(zhí)行模型

    CLR (Common Language Runtime) 是一個(gè)可以由多種編程語(yǔ)言使用的“運(yùn)行時(shí)”。
    2013-04-04
  • C#優(yōu)化if...else代碼的方案總結(jié)

    C#優(yōu)化if...else代碼的方案總結(jié)

    在編寫(xiě)代碼實(shí)現(xiàn)業(yè)務(wù)需求過(guò)程中,會(huì)使用到大量的if...else 判斷語(yǔ)句,隨業(yè)務(wù)復(fù)雜程度不同,導(dǎo)致判斷語(yǔ)句出現(xiàn)多層嵌套、多分支等情況,導(dǎo)致代碼可讀性變差、增加維護(hù)難度,本文介紹了C# 如何優(yōu)化 if...else 讓代碼優(yōu)雅起來(lái),需要的朋友可以參考下
    2024-06-06
  • c# 實(shí)現(xiàn)打印機(jī)狀態(tài)查詢(xún)與阻塞打印

    c# 實(shí)現(xiàn)打印機(jī)狀態(tài)查詢(xún)與阻塞打印

    這篇文章主要介紹了c# 引用System.Management來(lái)實(shí)現(xiàn)對(duì)打印機(jī)狀態(tài)的查詢(xún),幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-05-05
  • WPF自定義控件的實(shí)現(xiàn)

    WPF自定義控件的實(shí)現(xiàn)

    本文主要介紹了WPF自定義控件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • C# 實(shí)現(xiàn)繪制PDF嵌套表格案例詳解

    C# 實(shí)現(xiàn)繪制PDF嵌套表格案例詳解

    嵌套表格,顧名思義,就是在一張表格中的特定單元格中再插入一個(gè)或者多個(gè)表格,本文將為大家介紹C#繪制PDF嵌套表格的代碼示例,需要的同學(xué)可以參考一下
    2021-11-11
  • C#無(wú)損高質(zhì)量壓縮圖片代碼

    C#無(wú)損高質(zhì)量壓縮圖片代碼

    這篇文章主要為大家詳細(xì)介紹了C#無(wú)損高質(zhì)量壓縮圖片代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • C#設(shè)置MDI子窗體只能彈出一個(gè)的方法

    C#設(shè)置MDI子窗體只能彈出一個(gè)的方法

    這篇文章主要介紹了C#設(shè)置MDI子窗體只能彈出一個(gè)的方法,很實(shí)用的技巧,需要的朋友可以參考下
    2014-08-08
  • c#判斷輸入的是不是數(shù)字的小例子

    c#判斷輸入的是不是數(shù)字的小例子

    c#判斷輸入的是不是數(shù)字的小例子,需要的朋友可以參考一下
    2013-03-03
  • C#中計(jì)數(shù)排序算法的原理及實(shí)現(xiàn)

    C#中計(jì)數(shù)排序算法的原理及實(shí)現(xiàn)

    計(jì)數(shù)排序是一種線(xiàn)性時(shí)間復(fù)雜度的排序方法,主要通過(guò)統(tǒng)計(jì)元素出現(xiàn)的次數(shù)實(shí)現(xiàn)排序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10

最新評(píng)論

临西县| 星子县| 阳信县| 台中市| 安义县| 城市| 东光县| 岳普湖县| 卓资县| 富平县| 行唐县| 浮山县| 龙州县| 都昌县| 临泉县| 福州市| 宁阳县| 通道| 江安县| 集贤县| 彭阳县| 兴城市| 盐亭县| 江北区| 珠海市| 丹寨县| 贵南县| 米林县| 秀山| 桦甸市| 武胜县| 凭祥市| 自贡市| 昌吉市| 花莲县| 台安县| 九江县| 丰宁| 淅川县| 双牌县| 闽清县|