zoukankan      html  css  js  c++  java
  • 10-单例模式

    1. 单例模式的作用

        保证多个进程内,(即使多线程访问)该对象的实例只有一个,而且只会被创建一次。

    2. 单例模式什么时候用?

         该对象的构造函数非常耗时,实例化一次该对象,需要非常长的时间,这样如果每次都去创建,会消耗很多资源。

    3. 单例模式的代价

        private static Singleton _Singleton = null;  该静态对象不会被回收,会常驻内存。

    4. 特别注意

       单例只保证了实例的唯一,并不能保证实例中的方法或变量也唯一,所以单例中的方法或变量,在多线程面前,仍然可能是不安全的。

    5. 单例模式的三种写法

       双if+Lock(懒汉模式)、静态构造函数(饿汉模式)、静态变量(饿汉模式)。

       (1). 双if+Lock

       下面重点介绍“双if+Lock”由单线程→多线程的演变过程。

     1  public class SOne
     2     {
     3         /// <summary>
     4         /// 模拟耗时的构造函数
     5         /// </summary>
     6         public SOne()
     7         {
     8             long result = 0;
     9             for (int i = 0; i < 1000000; i++)
    10             {
    11                 result += i;
    12             }
    13             Thread.Sleep(1000);
    14             Console.WriteLine("{0}被构造...", this.GetType().Name);
    15         }
    16 
    17         private static SOne _Sone = null;
    18         private static object SoneLock = new object();
    19 
    20         /// <summary>
    21         /// 单线程内单例模式
    22         /// </summary>
    23         /// <returns></returns>
    24         public static SOne CreateIntance1()
    25         {
    26             //我们发现:在多线程中,实例创建了不止一次,原因是多个线程同时进入了
    27             if (_Sone == null)
    28             {
    29                 _Sone = new SOne();
    30             }
    31             return _Sone;
    32         }
    33         /// <summary>
    34         /// 多线程的单例模式(安全+但是费时,费在锁上了)
    35         /// </summary>
    36         /// <returns></returns>
    37         public static SOne CreateIntance2()
    38         {
    39             //给下面的语句整体加上锁,即使多线程,也需要一个一个的进入锁中进行判断,不存在同时进入创建实例内部的情况了。
    40             //缺点:同时带来一个问题,所有的线程必须等着前面一个锁完成后,方可进入,即使实例已经创建完了,也需要等前面的锁完成,这样多个线程耗时就耗在等锁上了
    41             lock (SoneLock)
    42             {
    43                 Console.WriteLine("我进入锁了,后面的要等我一下哦");
    44                 Thread.Sleep(1000); //模拟锁操作耗时
    45                 if (_Sone == null)
    46                 {
    47                     _Sone = new SOne();
    48                 }
    49             }
    50             return _Sone;
    51         }
    52 
    53         /// <summary>
    54         /// 多线程的单例模式(安全且不耗时)
    55         /// </summary>
    56         /// <returns></returns>
    57         public static SOne CreateIntance3()
    58         {
    59             //外层再加一层if,在进锁前就可以判断了,如果前面已经有实例创建好了,那么以后的就不需要等锁了,但是也可能存在多线程同时进入第一个if,那么同时进入的也要等一下哦。
    60             if (_Sone==null)
    61             {
    62                 lock (SoneLock)
    63                 {
    64                     Console.WriteLine("我进入锁了,后面的要等我一下哦");
    65                     //Thread.Sleep(1000); //模拟锁操作耗时
    66                     if (_Sone == null)
    67                     {
    68                         _Sone = new SOne();
    69                     }
    70                 }
    71             }      
    72             return _Sone;
    73         }
    74     }

       (2). 静态构造函数

     1    public class STwo
     2     {
     3         /// <summary>
     4         /// 模拟耗时的构造函数
     5         /// </summary>
     6         private STwo()
     7         {
     8             long result = 0;
     9             for (int i = 0; i < 1000000; i++)
    10             {
    11                 result += i;
    12             }
    13             Thread.Sleep(1000);
    14             Console.WriteLine("{0}被构造...", this.GetType().Name);
    15         }
    16 
    17         private static STwo _STwo = null;
    18         /// <summary>
    19         /// 静态的构造函数:只能有一个,且是无参数的
    20         /// 由CLR保证,只有在程序第一次使用该类之前被调用,而且只能调用一次
    21         /// </summary>
    22         static STwo()
    23         {
    24             _STwo = new STwo();
    25         }
    26 
    27         public static STwo CreateIntance()
    28         {
    29             return _STwo;
    30         }
    31     }

       (3). 静态变量

     1  public  class SThird
     2     {
     3         /// <summary>
     4         /// 模拟耗时的构造函数
     5         /// </summary>
     6         private SThird()
     7         {
     8             long result = 0;
     9             for (int i = 0; i < 1000000; i++)
    10             {
    11                 result += i;
    12             }
    13             Thread.Sleep(1000);
    14             Console.WriteLine("{0}被构造...", this.GetType().Name);
    15         }
    16         /// <summary>
    17         /// 静态变量:由CLR保证,在程序第一次使用该类之前被调用,而且只调用一次
    18         /// </summary>
    19         private static SThird _SThird = new SThird();
    20 
    21         public static SThird CreateIntance()
    22         {
    23             return _SThird;
    24         }
    25     }
  • 相关阅读:
    Linux 安装oracle客户端
    测试杂感:Bug Bash
    常用Eclipse插件在线安装地址
    [转]Source Insight使用小技巧小结
    cygwin安装
    Jmeter常见问题
    对测试人员或开发人员来说相互沟通有多重要?
    QTP基础学习(二)启动与设置
    什么是基准测试?
    推荐几款热门的网站测试工具
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7138700.html
Copyright © 2011-2022 走看看