设计模式之单例模式

目的:
保证一个类仅有一个实例,并提供一个访问它的全局访问点

实现方式:

1.最简单的方式

 public class Singleton
    {
        private static Singleton _instance;
        private Singleton()
        {
            Console.WriteLine("我被实例化了");
        }
        public static Singleton Instance
        {
            get
            {  
                return _instance == null ? (new Singleton()) : _instance;
            }
        }       
    }

 上面代码保证3点:第一,类不能被实例化(私有构造函数);第二,类不能被继承(私有构造函数);第三,提供一个全局访问的静态属性。

保证以上3点,单线程里我们就可以确保一个类只能提供一个实例,但是多线程下就不能确保了,我们看一下代码:

View Code
 class Program
    {
        static void Main(string[] args)
        {
            MultWork multThread = new MultWork();
            multThread.StartMultThread();
            Console.ReadLine();
        }
    }
    public class Singleton
    {
        private static Singleton _instance;
        private static readonly Object padlock = new object();
        private Singleton()
        {
            Console.WriteLine("我被实例化了");
        }
        public static Singleton Instance
        {
            get
            {                
                return _instance == null ? (new Singleton()) : _instance;
            }

        }

   }
    public class MultWork
    {
        private static readonly Object padlock = new object();
        /// <summary>
        
/// 线程工作
        
/// </summary>
        public static void DoSomeWork()
        {
            ///构造显示字符串
            string results = string.Empty;
            ///创建一个Sigleton实例
            Singleton MyCounter = Singleton.Instance;
            ///循环调用四次
            for (int i = 1; i < 5; i++)
            {               
                results += "线程";
                results += Thread.CurrentThread.Name.ToString();
                results += "\n";
            }
        }
        public void StartMultThread()
        {
            Thread thred0 = Thread.CurrentThread;
            thred0.Name = "主线线程";
            Thread thread1 = new Thread(new ThreadStart(DoSomeWork));
            thread1.Name = "thread1";
            thread1.Start();
            Thread thread2 = new Thread(new ThreadStart(DoSomeWork));
            thread2.Name = "thread2";
            thread2.Start();
            Thread thread3 = new Thread(new ThreadStart(DoSomeWork));
            thread3.Name = "thread3";
            thread3.Start();
            DoSomeWork();
        }

 我们新开了3个线程(包含主线程共4个线程),发现单例居然被实例化了4次,也就是说:每个线程独立实例化了Singleton,这可违背单例模式的初衷

 

2.惰性实例化

 为了解决线程的安全问题,我们可以在单例中加一个锁,保证同一时刻只能有一个线程访问,一旦存在实例,将不再实例化单例类,重新设计单例类代码如下:

View Code
public class Singleton
    {
        private static Singleton _instance;
        private static readonly Object padlock = new object();
        private Singleton()
        {
            Console.WriteLine("我被实例化了");
        }
        public static Singleton Instance
        {
            get
            {
                lock (padlock)
                    if (_instance == null)
                        _instance = new Singleton();
                return _instance;

            }

        }
}

 这样运行代码后发现无论启动多少个线程,都能保证类只有一个实例

 3.类型构造器方法(或者称为静态构造器法)

这种做法的优点是:让线程的安全性交给CLR来负责,这也是.NET中推荐的一种单例设计方式,代码如下:

 

View Code
 public  class Singleton
    {
        private static  Singleton _instance =null;        
        static Singleton()
        {
            Console.WriteLine("我被实例化了");
        }
        private Singleton()
        {
        }
        public static Singleton Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new Singleton();
                return _instance;

            }
        }     
    }

总之,以上就我在项目中经常使用的方式,当然还有其他更多的实现方式,你可以参看园子中其他大牛的文章,比如TerryLee的设计模式系列:http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html


原文地址:https://www.cnblogs.com/guanjie20/p/2344117.html