設計模式(七):單例模式

K戰神發表於2016-01-11

一、定義

單例就是一個例項。從始至終我們只需要維護這麼一個例項,來節約資源。

二、例項

我們用建構函式建立例項,現在我們要維護此類只維護一個例項,那麼我們需要將生產例項的能力也就是建構函式加以限制。

並通過一個統一的函式對外公開我們維護的唯一的例項。

2.1 第一代單例模式:利用懶載入,在確實要使用例項的時候才會建立單例

public class Single_1
    {
        private static Single_1 single = null;
        private Single_1()
        {
        }
        public static Single_1 GetInstance()
        {
            if (single == null)
            {
                single = new Single_1();
                Console.WriteLine("建立例項");
            }
            return single;
        }
    }

保證建立一個例項,但是隻是在單執行緒的環境下,如果多執行緒會怎麼樣?試試!!

客戶端併發100執行緒:

//------------------------單例模式-----------------------
            System.Threading.Tasks.Parallel.For(0, 100, t => { Singleton.Single_1.GetInstance(); });
            Console.ReadKey(); 

執行結果:執行結果由系統隨即切片,可能結果不同。但是確實存在建立了多個例項。

2.2 針對多執行緒之間的同步問題:加鎖

public class Single_2
    {
        private static Single_2 single = null;
        private static object lockkey = new object();
        private Single_2()
        {
        }
        public static Single_2 GetInstance()
        {
            lock (lockkey)
            {
                if (single == null)
                {

                    single = new Single_2();
                    Console.WriteLine("建立例項");
                }
                return single;
            }
        }
    }

效率高點的雙檢鎖:

 public static Single_2 GetInstance()
        {
            if (single == null)
            {
                lock (lockkey)
                {
                    if (single == null)
                    {
                        single = new Single_2();
                        Console.WriteLine("建立例項");
                    }                   
                }
            }
            return single;
        }

2.3 靜態建構函式構造單例:我們知道靜態建構函式是執行緒安全的

public class Single_3
    {
        private static Single_3 single = null;
        private Single_3()
        {
        }
        static Single_3()
        {
            single = new Single_3();
            Console.WriteLine("靜態例項");
        }

        public static Single_3 GetInstance()
        {
            return single;
        }
    }

三、總結

合理使用單例模式可以提高效能節約記憶體。當然,現實專案中有很多的例子,至少專案中可以很常見單例子模式。

相關文章