zoukankan      html  css  js  c++  java
  • 简单的研究了一下单例模式

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

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

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

      再次执行一次

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

  • 相关阅读:
    CodeForces 757C Felicity is Coming!(排列组合)
    Ural 1519 Formula 1( 插头dp )
    FZU 2187 回家种地 ( 扫描线 + 离散 求矩阵单次覆盖面积 )
    HDU 1255 覆盖的面积 ( 扫描线 + 离散 求矩阵大于k次面积并 )
    ZOJ 3841 Cards
    HDU 4012 Paint on a Wall(状压+bfs)
    Topcoder SRM653div2
    2015 GDUT校赛
    Topcoder SRM652div2
    CodeChef A String Game(SG)
  • 原文地址:https://www.cnblogs.com/myblogslh/p/5321570.html
Copyright © 2011-2022 走看看