C#设计模式之单例模式

匿名 (未验证) 提交于 2019-12-02 23:05:13

1.什么是单例模式?

确保一个类只有一个实例,并提供一个全局访问点。

通俗易懂就是:每次去实例化一个对象都是同一个,指向的都是同一个内存地址。

2.为什么要使用单例模式,单例模式的好处在哪?

3.单例模式在C#中的具体实现。

 /// <summary>     /// 单例模式的简单实现     /// </summary>     public class Singleton     {         /// <summary>         /// 创建全局静态变量         /// </summary>         private static Singleton _singleton = null;         /// <summary>         /// 私有化默认构造器,为什么要私有化默认构造器,如果不私有,那么可以通过new Singleton()进行实例化对象了,就达不到预想效果。         /// </summary>         private Singleton()         {          }         /// <summary>         /// 提供一个创建实例的方法         /// </summary>         /// <returns></returns>         public static Singleton CreatInstance()         {             //判断,如果对象没有创建,那么进行创建。有创建,不在重复创建             if (_singleton == null)             {                 _singleton=new Singleton();             }             return _singleton;         }     } 

  测试结果如下:

 //多线程模拟,十个线程同时访问             for (int i = 0; i < 10; i++)             {                 new Action(() =>                 {                     Thread.Sleep(1000);                     Singleton singleton = Singleton.CreatInstance();                     singleton.Show(); //在Singleton类里面添加一个无参的Show方法                  }).BeginInvoke(null, null);             } 

  

            //判断,如果对象没有创建,那么进行创建。有创建,不在重复创建             if (_singleton == null)             {                 _singleton=new Singleton();             } 

 会去判断这个对象是否已经被实例化,因为程序执行速度是很快的,当第一个线程发现对象未实例化时,第一个线程开始对对象进行实例化,第一个线程还未实例化完成第二个线程就已经进来了,开始对对象进行判断,开始实例化。最终造成如上效果。

 public class Singleton     {         /// <summary>         /// 创建全局静态变量         /// </summary>         private static Singleton _singleton = null;         private static object singleton_lock=new object();         /// <summary>         /// 私有化默认构造器         /// </summary>         private Singleton()         {             Console.WriteLine("创建了Singleton对象的实例");         }         /// <summary>         /// 提供一个创建实例的方法         /// </summary>         /// <returns></returns>         public static Singleton CreatInstance()         {             lock (singleton_lock)             {                 //判断,如果对象没有创建,那么进行创建。有创建,不再重复创建                 if (_singleton == null)                 {                     _singleton = new Singleton();                 }             }             return _singleton;         }         public void Show()         {             Console.WriteLine($"执行Show方法:{this.GetType()}");         }     } 

  运行后如下图:

多线程同时访问的情况下的问题就已经解决了。当然还可以再次优化一下,为了看到效果,对代码进行如下改造

改造之后再次执行

如上图发现,每一个线程都进入lock里面,如果第一个线程进入lock实例化了对象,那么第二个就可以没有必要进入lock,我们可以在线程进入lock前进行判断,最终代码改造如下,

 /// <summary>     /// 单例模式的简单实现     /// </summary>     public class Singleton     {         /// <summary>         /// 创建全局静态变量         /// </summary>         private static Singleton _singleton = null;         private static object singleton_lock=new object();         /// <summary>         /// 私有化默认构造器         /// </summary>         private Singleton()         {             Console.WriteLine("创建了Singleton对象的实例");         }         /// <summary>         /// 提供一个创建实例的方法         /// </summary>         /// <returns></returns>         public static Singleton CreatInstance()         {             if (_singleton == null)             {                 lock (singleton_lock)                 {                     Console.WriteLine("开始进入lock...");                     //判断,如果对象没有创建,那么进行创建。有创建,不在重复创建                     if (_singleton == null)                     {                         _singleton = new Singleton();                     }                 }             }             return _singleton;         }         public void Show()         {             Console.WriteLine($"执行Show方法:{this.GetType()}");         }     } 

  执行效果如下

图中发现线程进入lock的次数少了,线程并发少可能作用不大,如果是并发量达到百万次甚至更多,那么效率会有明显提升。双if加lock是最标准的实现单例模式的写法。

接下来介绍两种比较简便的单例模式的实现,效果和上面的一样。

方式二、

 public class SingletonSecond     {         private static SingletonSecond _singletonSecond = new SingletonSecond();         private SingletonSecond()         {             Console.WriteLine("创建了该对象的实例");         }          public static SingletonSecond CreatInstance()         {             return _singletonSecond;         }         public void Show()         {             Console.WriteLine($"执行Show方法:{this.GetType()}");         }     } 

  

方式三、

 public class SingletonThrird     {         private static SingletonThrird _singletonThrid = null;         private SingletonThrird()         {             Console.WriteLine("创建了该对象的实例");         }         static SingletonThrird()         {             _singletonThrid=new SingletonThrird();         }         public static SingletonThrird CreatInstance()         {             return _singletonThrid;         }         public void Show()         {             Console.WriteLine($"执行Show方法:{this.GetType()}");         }     } 

  

以上就单例模式的实现方式。提供参考,职场小白欢迎指正!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!