#概述 單例模式就是保證在整個應用程序的生命週期中,在任什麼時候刻,被指定的類只有一個實例,併爲客戶程序提供一個獲取該實例的全局訪問點。數據庫
單例模式是一種經常使用的軟件設計模式。在它的核心結構中只包含一個被稱爲單例的特殊類。經過單例模式能夠保證系統中一個類只有一個實例並且該實例易於外界訪問,從而方便對實例個數的控制並節約系統資源。若是但願在系統中某個類的對象只能存在一個,單例模式是最好的解決方案。windows
保證一個類僅有一個實例,並提供一個該實例的全局訪問點。設計模式
1.將該類的構造方法定義爲私有方法,這樣其餘處的代碼就沒法經過調用該類的構造方法來實例化該類的對象,只有經過該類提供的靜態方法來獲得該類的惟一實例; 2.在該類內提供一個靜態方法,當咱們調用這個方法時,若是類持有的引用不爲空就返回這個引用,若是類保持的引用爲空就建立該類的實例並將實例的引用賦予該類保持的引用。安全
public class Singleton { private static Singleton _instance = new Singleton(); private Singleton() { } public static Singleton Instance() { return _instance; } }
適用:單/多線程 模式:餓漢式(靜態常量)[可用] 優勢:寫法比較簡單,避免了線程同步問題 缺點:沒能實現延遲加載多線程
public class Singleton2 { private static Singleton2 _instance; static Singleton2() { _instance = new Singleton2(); } private Singleton2(){} public Singleton2 Instance() { return _instance; } }
適用:單/多線程 模式:餓漢式(靜態代碼塊)[可用] 優勢:寫法比較簡單,避免了線程同步問題 缺點:沒能實現延遲加載性能
public class Singleton3 { private static Singleton3 _instance; private Singleton3() { } public static Singleton3 Instance() { return _instance ?? (_instance = new Singleton3()); } }
適用:單線程 模式:懶漢式(線程不安全)[不可用] 優勢:適用於單線程,實現簡單,延遲加載 缺點:多線程不安全,違背了單列模式的原則網站
public class Singleton4 { private static Singleton4 _instance; private static readonly object SyncObject = new object(); private Singleton4() { } public static Singleton4 Instance() { lock (SyncObject) { if (_instance == null) { _instance = new Singleton4(); } } return _instance; } }
適用:單線程 模式:懶漢式(線程安全)[不推薦] 優勢:線程安全;延遲加載; 缺點:這種實現方式增長了額外的開銷,損失了性能(當有多個調用時,第一個調用的會進入lock,而其餘的則等待第一個結束後才能調用,後面的依次訪問、等待……)操作系統
public class Singleton5 { private static Singleton5 _instance; private static readonly object SyncObject = new object(); private Singleton5() { } public static Singleton5 Instance() { if (_instance==null) { lock (SyncObject) { if (_instance == null) { _instance = new Singleton5(); } } } return _instance; } }
適用:單/多線程 模式:雙重檢查鎖定(Double-Check Locking)(線程安全)[推薦] 優勢:線程安全;延遲加載;效率較高(只會實例化一次,首先會判斷是否實例化過,若是實例化了,直接返回實例,不須要進入lock;若是未實例化,進入lock,就算是多個調用也無妨,第一次調用的會實例化,第二個進入lock時會再次判斷是否實例化,這樣線程就不會阻塞了。) 缺點:基本沒有線程
public class Singleton6 { private Singleton6() { } private static class SingletonInstance { public static Singleton6 Instance = new Singleton6(); } public static Singleton6 Instance() { return SingletonInstance.Instance; } }
適用:單/多線程 模式:靜態內部類(線程安全)[推薦] 優勢:避免了線程不安全;延遲加載;效率高(這種方式跟餓漢式方式採用的機制相似:都是採用了類裝載的機制來保證初始化實例時只有一個線程。不一樣的地方是:餓漢式只要Singleton類被裝載就會實例化,沒有Lazy-Loading的做用;而靜態內部類方式在Singleton類被裝載時並不會當即實例化,而是在須要實例化時,調用Instance方法,纔會裝載SingletonInstance類,從而完成Singleton的實例化。) 缺點:基本沒有設計