1. 程式人生 > 實用技巧 >設計模式建立型之單例模式

設計模式建立型之單例模式

單例就是在應用程式中保證型別只有一個例項。

建立一個簡單的單例,程式碼如下

 public class Singleton
    {
        private Singleton() //構造私有化,防止外部New
        {
            
        }

        private static Singleton _singleton = null;

        //對外提供一個獲取例項的方法
        public static Singleton CreateInstance()
        {
            if (_singleton == null
) { _singleton= new Singleton(); } return _singleton; } }

這樣存在的問題是多執行緒時,執行緒不安全,升級如下

 public class Singleton
    {
        private Singleton() //構造私有化,防止外部New
        {
            
        }

        private static Singleton _singleton = null
; private static object _lockObject = new object(); //對外提供一個獲取例項的方法 public static Singleton CreateInstance() { lock (_lockObject)//確保任意時刻只有一個執行緒訪問 { if (_singleton == null) { _singleton = new Singleton(); } }
return _singleton; } }

執行緒安全,但是有效能問題,繼續升級如下

 public class Singleton
    {
        private Singleton() //構造私有化,防止外部New
        {
            
        }

        private static Singleton _singleton = null;

        private static object _lockObject = new object();
        //對外提供一個獲取例項的方法
        public static Singleton CreateInstance()
        {
            if (_singleton == null) //對像不為空時直接返回,不用排隊取鎖,提高效能
            {
                lock (_lockObject)//確保任意時刻只有一個執行緒訪問
                {
                    if (_singleton == null)
                    {
                        _singleton = new Singleton();
                    }
                }
            }
            
            return _singleton;
        }
    }

這樣通過雙if加lock ,就實現了一個懶漢式的單例。

懶漢式 :需要才建立例項,延遲載入

餓漢式 :第一時間建立例項,類載入就馬上建立

接下來實現兩種餓漢式的單例

1靜態方法中初始化物件

public class Singleton
    {
        private Singleton() //構造私有化,防止外部New
        {
            
        }
      
        private static Singleton _singleton = null;

        //靜態建構函式:由CLR保證單例,程式第一次使用這個型別前被呼叫,且只調用一次
        static Singleton()
        {
            _singleton = new Singleton();
        }

        //對外提供一個獲取例項的方法
        public static Singleton CreateInstance()
        {            
            return _singleton;
        }
    }

2 靜態欄位賦值

public class Singleton
    {
        private Singleton() //構造私有化,防止外部New
        {
            
        }

        //靜態欄位:在第一次使用這個類之前,由CLR保證,初始化且只初始化一次
        private static Singleton _singleton = new Singleton();

        //對外提供一個獲取例項的方法
        public static Singleton CreateInstance()
        {            
            return _singleton;
        }
    }

單例模式建立的例項不會自動釋放記憶體,會長時間佔據記憶體空間。適用場景執行緒池,資料庫連線池,計數器/流水號生成器,配置檔案讀取,IOC容器。