简单的研究了一下单例模式

  之前我喜欢只是单纯的记记笔记,没有什么写文章的习惯,今天也是我一边研究一边学习,索性就连过程什么的都记录下吧,或许能帮到一两个朋友呢。

  首先,我们来想想什么叫做单例,顾名思义,单一的一个对象,那么,单一模式有什么好处呢?比如说,你的对象只可以实例化一次等等。

  先写一个简单的测试里的例子吧,比如我建一个类,叫做TestSingle

  

1  /// <summary>
2     /// 单例模式简单的例子(sealed,不可继承)
3     /// </summary>
4     public sealed class TestSingle
5     {
6     }

  首先要让这个类不可继承,要不然就没有意义了,那么,接下来做什么呢?让一个对象只实例化一次,从而降低等等一些乱七八糟的东西。专业名词很多,百度搜搜就可以看到了。我们在实例化一个对象会做什么呢?肯定是new一个对象了,那么new对象的时候会发生什么事情呢?就是执行构造函数,那如何让我们这个类只实例化一次呢?看样子只能从构造函数入手了。

  

 1  /// <summary>
 2         /// 用来记录构造函数执行的次数
 3         /// </summary>
 4         private static int structureCount = 0;
 5 
 6         /// <summary>
 7         /// 私有的无参构造函数
 8         /// </summary>
 9         private TestSingle() 
10         {
11             structureCount++;
12             Console.WriteLine("只是第{0}次执行构造函数", structureCount);
13         } 

  首先我定义了一个静态的变量用来存储构造函数执行的次数,并在构造函数中输出执行的次数。当我把构造函数私有化之后,如何通过别的方式来让外界访问到呢?我们来写一个public的方法,来提供外界的调用,当然,这个方法也是一个静态的方法。

 1  /// <summary>
 2         /// 实例化时执行的此处
 3         /// </summary>
 4         private static int createStructureCount = 0;
 5 
 6         /// <summary>
 7         /// TestSingle
 8         /// </summary>
 9         private static TestSingle testSingle = null;
10 
11 
12   /// <summary>
13         /// 创建一个testSingle的实例
14         /// </summary>
15         /// <returns></returns>
16         public static TestSingle CreateTestSingle()
17         {
18             createStructureCount++;
19             Console.WriteLine("我是第{0}次创建TestSingle实例化", createStructureCount);
20             testSingle = new TestSingle();
21             return testSingle;
22         }

  这样写和一个普通的new又有什么区别?我们来把方法改造一下

 1  /// <summary>
 2         /// 创建一个testSingle的实例
 3         /// </summary>
 4         /// <returns></returns>
 5         public static TestSingle CreateTestSingle()
 6         {
 7             createStructureCount++;
 8             Console.WriteLine("我是第{0}次创建TestSingle实例化", createStructureCount);
 9             if (testSingle == null)
10             {
11                 testSingle = new TestSingle();
12             }
13             return testSingle;
14         }

  我们去执行一下测试一下看效果如何。

  我们可以看到构造函数被执行了两次,我电脑的CPU性能并不是很好,如果好一点的电脑可能会执行更多次。那么我是怎么进行测试的呢?我写了一个线程工厂,不停的去CreateTestSingle

 1  static void Main(string[] args)
 2         {
 3             //创建一个Task工厂
 4             TaskFactory taskFactory = new TaskFactory();
 5             for (int i = 0; i < 20; i++)
 6             {
 7                 taskFactory.StartNew(() => TestSingle.CreateTestSingle());
 8             }
 9             Console.ReadLine();
10         }

  也就是说,在很多个线程同时去Create的时候,不妨还是new了多个对象。所以光这样是不行的,所以我加了一个锁和双层判断

  

 1   /// <summary>
 2         /// 锁定对象
 3         /// </summary>
 4         private static object lock_SingleTest = new object();
 5 
 6   /// <summary>
 7         /// 创建一个testSingle的实例
 8         /// </summary>
 9         /// <returns></returns>
10         public static TestSingle CreateTestSingle()
11         {
12             if (testSingle == null)
13             {
14                 lock (lock_SingleTest)
15                 {
16                     if (testSingle == null)
17                     {
18                         testSingle = new TestSingle();
19                     }
20                    
21                 }
22             }
23             createStructureCount++;
24             Console.WriteLine("我是第{0}次创建TestSingle实例化", createStructureCount);
25             return testSingle;
26         }

  再次执行一次

  这样的话,不管我执行多少次,构造函数都始终只会被执行一次。大家可以让线程睡眠后再打印看看结果,那样我想你就可以看的出来效果了。哦了,这样我们就把单例模式创建完了。

原文地址:https://www.cnblogs.com/myblogslh/p/5321570.html