欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#實(shí)現(xiàn)單例模式的多種方式

 更新時(shí)間:2022年01月25日 10:09:28   作者:痕跡g  
這篇文章介紹了C#實(shí)現(xiàn)單例模式的多種方式,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

什么是單例模式?

這里我就不做過多的解釋了, 畢竟關(guān)于Singleton的資料實(shí)在是太多太多了。點(diǎn)擊這里

簡(jiǎn)單的思路就是, 創(chuàng)建對(duì)象單例的動(dòng)作轉(zhuǎn)移到另外的行為上面, 利用一個(gè)行為去創(chuàng)建對(duì)象自身, 如下:

public class Singleton
    {
       private Sington() { }
        private static Singleton _Singleton = null;
        public static Singleton CreateInstance()
        {
            if (_Singleton == null)
            {
             Console.WriteLine("被創(chuàng)建");
             _Singleton = new Singleton();
            }
            return _Singleton;
        }
    }

這樣寫看上去是沒有問題, 但是有沒有那種可能, 同時(shí)兩個(gè)動(dòng)作都判斷這個(gè)對(duì)象為空, 那么這個(gè)對(duì)象就會(huì)被創(chuàng)建2次?是的, 多線程中, 這樣是無法保證單例。

就像這樣, 同時(shí)創(chuàng)建多個(gè)線程去創(chuàng)建這個(gè)對(duì)象實(shí)例的時(shí)候, 會(huì)被多次創(chuàng)建, 這個(gè)時(shí)候, 對(duì)代碼改進(jìn)一下。

public class Singleton
    {
       private Sington() { }
        private static Singleton _Singleton = null;
        private static object Singleton_Lock = new object(); //鎖同步
        public static Singleton CreateInstance()
        {
                lock (Singleton_Lock)
                {
            Console.WriteLine("路過");
                    if (_Singleton == null)
                    {
              Console.WriteLine("被創(chuàng)建");
                        _Singleton = new Singleton();
                    }
                }
            return _Singleton;
        }
    }

調(diào)試代碼:

                TaskFactory taskFactory = new TaskFactory();
                List<Task> taskList = new List<Task>();

                for (int i = 0; i < 5; i++)
                {
                    taskList.Add(taskFactory.StartNew(() =>
                     {
                         Singleton singleton = Singleton.CreateInstance(); 
                     }));
                }

結(jié)果:

上面, 我們創(chuàng)建了多個(gè)線程,同時(shí)去創(chuàng)建這個(gè)對(duì)象的實(shí)例, 在第二次,對(duì)象命名已經(jīng)被創(chuàng)建了, 盡管只創(chuàng)建了一次滿足了我們的需求, 但是我們已知對(duì)象被創(chuàng)建了, 還需要進(jìn)來做不必要的動(dòng)作嗎?

我們都知道, 同步鎖為了達(dá)到預(yù)期的效果, 也是損耗了性能的, 那么下面的輸出, 很顯然是沒必要的動(dòng)作, 所以我們優(yōu)化一下。

    public class Singleton
    {
        private static Singleton _Singleton = null;
        private static object Singleton_Lock = new object();
        public static Singleton CreateInstance()
        {
            if (_Singleton == null) //雙if +lock
            {
                lock (Singleton_Lock)
                {
                    Console.WriteLine("路過。");
                    if (_Singleton == null)
                    {
                        Console.WriteLine("被創(chuàng)建。");
                        _Singleton = new Singleton();
                    }
                }
            }
            return _Singleton;
        }
    }

結(jié)果:

很顯然, 這樣達(dá)到了我們的預(yù)期, 對(duì)象在被創(chuàng)建后, 就沒必要做多余的行為。

利用靜態(tài)變量實(shí)現(xiàn)單例模式

 public sealed class Singleton
    {
        private Singleton() { }

        private static readonly Singleton singleInstance = new Singleton();

        public static Singleton GetInstance
        {
            get
            {
                return singleInstance;
            }
        }
    }

是不是覺得很優(yōu)雅, 利用靜態(tài)變量去實(shí)現(xiàn)單例, 由CLR保證,在程序第一次使用該類之前被調(diào)用,而且只調(diào)用一次

PS: 但是他的缺點(diǎn)也很明顯, 在程序初始化后, 靜態(tài)對(duì)象就被CLR構(gòu)造了, 哪怕你沒用。

利用靜態(tài)構(gòu)造函數(shù)實(shí)現(xiàn)單例模式

 public class SingletonSecond
    {
        private static SingletonSecond _SingletonSecond = null;

        static SingletonSecond()
        {
            
            _SingletonSecond = new SingletonSecond();
        }
        
        public static SingletonSecond CreateInstance()
        {
            return _SingletonSecond;
        }
    }

靜態(tài)構(gòu)造函數(shù):只能有一個(gè),無參數(shù)的,程序無法調(diào)用 。

同樣是由CLR保證,在程序第一次使用該類之前被調(diào)用,而且只調(diào)用一次。同靜態(tài)變量一樣, 它會(huì)隨著程序運(yùn)行, 就被實(shí)例化, 同靜態(tài)變量一個(gè)道理。

單例模式中的延遲加載

延遲加載或延遲加載是一種設(shè)計(jì)模式,或者您可以說這是一個(gè)概念,通常用于將對(duì)象的初始化延遲到需要時(shí)。因此,延遲加載的主要目標(biāo)是按需加載對(duì)象,或者您可以根據(jù)需要說出對(duì)象。

作為 .NET Framework 4.0 的一部分引入的惰性關(guān)鍵字為惰性初始化(即按需對(duì)象初始化)提供了內(nèi)置支持。如果要使對(duì)象(如 Singleton)以延遲初始化,則只需將對(duì)象的類型(單例)傳遞給lazy關(guān)鍵字,如下所示。

private static readonly Lazy<Singleton> Instancelock = new Lazy<Singleton>(() => new Singleton());
 public sealed class Singleton
     {
         private Singleton()
         {}
 
         private static readonly Lazy<Singleton> Instancelock =
                     new Lazy<Singleton>(() => new Singleton());
 
         public static Singleton GetInstance
         {
             get
             {
                 return Instancelock.Value;
             }
         }
     }

到此這篇關(guān)于C#實(shí)現(xiàn)單例模式的多種方式的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在Parallel中使用DbSet.Add()發(fā)現(xiàn)的一系列多線程問題和解決思路詳解

    在Parallel中使用DbSet.Add()發(fā)現(xiàn)的一系列多線程問題和解決思路詳解

    這篇文章主要介紹了在Parallel中使用DbSet.Add()發(fā)現(xiàn)的一系列多線程問題和解決過程的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • C#帶你玩掃雷(附源碼)

    C#帶你玩掃雷(附源碼)

    這篇文章主要介紹了C#帶你玩掃雷(附源碼),詳細(xì)的介紹實(shí)現(xiàn)掃雷的方法,具體一定的參考價(jià)值,有興趣的可以了解一下
    2017-10-10
  • C#自動(dòng)創(chuàng)建數(shù)據(jù)庫實(shí)現(xiàn)代碼

    C#自動(dòng)創(chuàng)建數(shù)據(jù)庫實(shí)現(xiàn)代碼

    C#下創(chuàng)建數(shù)據(jù)庫的代碼
    2008-03-03
  • c# WPF設(shè)置軟件界面背景為MediaElement并播放視頻

    c# WPF設(shè)置軟件界面背景為MediaElement并播放視頻

    這篇文章主要介紹了c# WPF如何設(shè)置軟件界面背景為MediaElement并播放視頻,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03
  • C# 位運(yùn)算符整理

    C# 位運(yùn)算符整理

    在C#中可以對(duì)整型運(yùn)算對(duì)象按位進(jìn)行邏輯運(yùn)算。按位進(jìn)行邏輯運(yùn)算的意義是:依次取被運(yùn)算對(duì)象的每個(gè)位,進(jìn)行邏輯運(yùn)算,每個(gè)位的邏輯運(yùn)算結(jié)果是結(jié)果值的每個(gè)位。
    2008-10-10
  • Unity UGUI的Image圖片組件使用詳解

    Unity UGUI的Image圖片組件使用詳解

    這篇文章主要為大家介紹了Unity UGUI的Image圖片組件使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • WPF應(yīng)用程序本地化的最佳方法分享

    WPF應(yīng)用程序本地化的最佳方法分享

    應(yīng)用程序本地化有很多種方式,選擇合適的才是最好的,這篇文章主要為大家介紹了動(dòng)態(tài)資源的方式,可以在不重啟應(yīng)用程序的情況下進(jìn)行資源的切換,需要的可以參考下
    2023-08-08
  • C#數(shù)據(jù)庫連接方式(類的形式)

    C#數(shù)據(jù)庫連接方式(類的形式)

    這篇文章主要介紹了C#數(shù)據(jù)庫連接方式(類的形式),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • c#中的interface abstract與virtual介紹

    c#中的interface abstract與virtual介紹

    abstract 與virtual : 方法重寫時(shí)都使用 override 關(guān)鍵字,interface中的方法和abstract方法都要求實(shí)現(xiàn)
    2013-07-07
  • C#并行編程之?dāng)?shù)據(jù)并行Tasks.Parallel類

    C#并行編程之?dāng)?shù)據(jù)并行Tasks.Parallel類

    這篇文章介紹了C#并行編程之?dāng)?shù)據(jù)并行Tasks.Parallel類,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05

最新評(píng)論