当前位置: 代码迷 >> C# >> 简略的研究了一下单例模式
  详细解决方案

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

热度:176   发布时间:2016-04-28 08:21:39.0
简单的研究了一下单例模式

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

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

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

  

1  /// <summary>2     /// 单例模式简单的例子(sealed,不可继承)3     /// </summary>4     public sealed class TestSingle5     {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         }

  再次执行一次

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

  相关解决方案