C# 單例模式

來源:互聯網
上載者:User

標籤:

    一、多線程不安全方式實現

 public sealed class SingleInstance    {        private static SingleInstance instance;        private SingleInstance() { }        public static SingleInstance Instance        {            get            {                if (null == instance)                {                    instance = new SingleInstance();                }                return instance;            }        }    }

  sealed表示SingleInstance不能被繼承。其實建構函式私人化已經達到了這個效果,私人的建構函式不能被繼承。為了可讀性,可以加個sealed。

不安全的單例指的是在多線程環境下可能有多個線程同時進入if語句,建立了多次單例對象。

   二、安全的單例模式

  public sealed class SingleInstance    {        private static volatile SingleInstance instance;        private static readonly object obj = new object();        private SingleInstance() { }        public static SingleInstance Instance        {            get            {                if (null == instance)                {                    lock (obj)                    {                        if (null == instance)                        {                            instance = new SingleInstance();                        }                    }                }                return instance;            }        }    }

 加鎖保護,在多線程下可以確保執行個體值被建立一次。缺點是每次擷取單例,都要進行判斷,涉及到的鎖和解鎖比較耗資源。

三、唯讀屬性式

 public sealed class SingleInstance    {        private static readonly SingleInstance instance = new SingleInstance();        private SingleInstance() { }        public static SingleInstance Instance        {            get            {                return instance;            }        }    }

   藉助readonly屬性,instance只被初始化一次,同樣達到了單例的效果。在Main函數執行第一句話之前,instance其實已經被賦值了,並不是預期的 只有到訪問Instance變數時才建立對象。

如下代碼:

 class Program    {        static void Main(string[] args)        {            Console.WriteLine("Begin");            var temp = SingleInstance.instance; ;        }    }    public sealed class SingleInstance    {        public static readonly SingleInstance instance = new SingleInstance();        private SingleInstance()        {            Console.WriteLine("初始化初始化!");        }        public static SingleInstance Instance        {            get { return instance; }        }    }

  輸出:

在執行第一句代碼之前,執行個體已經被初始化。

解決方案是在SingleInstance中加上靜態建構函式。

 public sealed class SingleInstance    {        public static readonly SingleInstance instance = new SingleInstance();        static SingleInstance() { }        private SingleInstance()        {            Console.WriteLine("初始化初始化!");        }        public static SingleInstance Instance        {            get { return instance; }        }    }

  在運行輸出:

   

 

四、使用Lazy

 public sealed class SingleInstance    {        private static readonly Lazy<SingleInstance> instance = new Lazy<SingleInstance>(() => new SingleInstance());        private SingleInstance(){}        public static SingleInstance Instance        {            get            {                return instance.Value;            }        }    }

  Lazy預設是安全執行緒的。MSDN描述如下:

 Will the lazily initialized object be accessed from more than one thread? If so, the Lazy<T> object might create it on any thread. You can use one of the simple constructors whose default behavior is to create a thread-safe Lazy<T> object, so that only one instance of the lazily instantiated object is created no matter how many threads try to access it. To create a Lazy<T> object that is not thread safe, you must use a constructor that enables you to specify no thread safety.

   

五、泛型單例

    class Program    {        static void Main(string[] args)        {            Console.WriteLine("Begin");            mySingle.Instance.age = 500;            Console.WriteLine(mySingle.Instance.age);        }    }    public abstract class SingleInstance<T>    {        private static readonly Lazy<T> _instance = new Lazy<T>(() =>            {                var ctors = typeof(T).GetConstructors(BindingFlags.Instance| BindingFlags.NonPublic| BindingFlags.Public);                if (ctors.Count() != 1)                    throw new InvalidOperationException(String.Format("Type {0} must have exactly one constructor.", typeof(T)));                var ctor = ctors.SingleOrDefault(c => c.GetParameters().Count() == 0 && c.IsPrivate);                if (ctor == null)                    throw new InvalidOperationException(String.Format("The constructor for {0} must be private and take no parameters.", typeof(T)));                return (T)ctor.Invoke(null);            });        public static T Instance        {          get{ return _instance.Value;}        }    }    public class mySingle : SingleInstance<mySingle>    {        private mySingle() { }        public int age;    }

  

C# 單例模式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.