你的位置:首页 > ASP.net教程

[ASP.net教程]简单的研究了一下单例模式


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

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

  先写一个简单的测试里的例子吧,比如我建一个类,叫做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     }

  再次执行一次

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