設計模式之一(單例模式)


前言

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

通常我們可以讓一個全局變量使得一個對象被訪問,但它不能防止你實例化多個對象。一個最好的辦法就是,讓類自身負責保存它的唯一實例。這個類可以保證沒有其他實例可以被創建,並且它可以提供一個訪問該實例的方法。

單例模式

    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)   ///在同一個程序加了鎖的那部分程序只有一個線程可以加入
                {
            ///若實例不存在,則new一個新實例,否則返回已有的實例      
if (instance == null) { instance = new Singleton(); } } } return instance; } }

說明:

構造方法private Singleton(){},讓其private,這樣就堵死了外界利用new創建此類實例的可能

public static Singleton GetInstance() 此方法是獲得本類實例的唯一全局訪問點

lock:是確保當一個線程位於代碼的臨界區時,另一個線程不進入臨界區。如果其他線程試圖進入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。

然后在上面的Singleton類中添加一個測試方法

        //類函數
        public void Test()
        {
            Console.WriteLine("Hello World!");
        }

最后即可在控制台應用程序的入口函數進行調用測試

    class Program
    {
        static void Main(string[] args)
        {
            Singleton.GetInstance().Test();
            Console.ReadLine();
        }
    }

結果也Ok

            Singleton s1 = Singleton.GetInstance();
            Singleton s2 = Singleton.GetInstance();
            if (s1 == s2)
            {
                Console.WriteLine("兩個對象是相同的實例");
            }

繼續在Main函數中添加實例代碼,判斷兩個實例化對象是否為一個對象。

 

靜態初始化

 其實咋實際應用當中,C#與公共語言運行庫也提供了一種“靜態初始化”方法,這種方法不需要開發人員顯示的編寫線程安全代碼,即可解決多線程環境下它是不安全的問題。

    public sealed class Singletons
    {
        private static readonly Singletons instance = new Singletons();   
        private Singletons() { }
        public static Singletons GetInstance()
        {
            return instance;
        }
    }

通過sealed修飾符來修飾類,是阻止發生派生,而派生可能會增加實例

在第一次引用類的任何成員時創建實例。公共語言運行庫負責處理變量初始化。並通過readonly標記instance變量,這意味着只能在靜態初始化期間或在類構造函數中分配變量。由於這種靜態初始化的方式是在自己被加載時就將自己實例化,所以被形象的稱之為餓漢式單例類,上面的單例模式處理方式是要在第一次被引用時,才會將自己實例化,所以就被成為懶漢式單例類。

總結

 餓漢式,即靜態初始化的方式,它是類一加載就實例化對象,所以要提前占用系統資源。然后懶漢式,又會面臨着多線程訪問的安全性問題,需要做雙重鎖定這樣的處理才可以保證安全。送一到底使用哪一種方式,取決於實際的需求。從C#語言的角度來講,餓漢式的單例類已經足夠滿足我們的需求了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM