zoukankan      html  css  js  c++  java
  • 单例

    几乎所有的人都能对单例进行一般的解释,但是真正让他们手写一段单例代码的时候,能写得清楚明白的人就没几个了。下面我们一起来总结一下怎么写出一个好的单例。[源代码从这里下载]

    目录
    一、非线程安全的单例
    二、未采用延迟加载的单例
    三、采用线程同步方法实现的单例
    四、采用双重锁实现的单例 
    五、【结论】采用原子操作实现的单例 

    一、非线程安全的单例:

     1     public class Singleton
    2 {
    3 private static Singleton instance;
    4 private Singleton() { }
    5
    6 public static Singleton GetInstance
    7 {
    8 get
    9 {
    10 if(null == instance)
    11 {
    12 instance = new Singleton();
    13 }
    14 return instance;
    15 }
    16 }
    17 }

    这种写法存在的问题是,当并发调用GetInstance属性的时候,由于多个线程同时进入了if判断,从而造成返回多个Singleton对象的隐患。这自然就有违我们的单例模式了。

    二、未采用延迟加载的单例:

     1     public class Singleton
    2 {
    3 private static Singleton instance = new Singleton();
    4 private Singleton() { }
    5
    6 public static Singleton GetInstance
    7 {
    8 get { return instance; }
    9 }
    10 }

    由于采用框架特性,这种写法确实是线程安全的,但是类型一旦加载,单例对象就已经存在,造成多余开销,如果构造函数耗时比较长的话,影响就更为突出了。

    三、采用线程同步方法实现的单例:

     1     public class Singleton
    2 {
    3 private static Singleton instance;
    4 private Singleton() { }
    5
    6 [MethodImpl(MethodImplOptions.Synchronized)]
    7 public static Singleton GetInstance()
    8 {
    9 if (null == instance)
    10 {
    11 instance = new Singleton();
    12 }
    13 return instance;
    14 }
    15 }

    线程安全了,也延迟加载了,但是新的问题又来了,由于GetInstance方法在任何时候都只允许一个线程进入,带来的性能损失是不可忽视的。

    四、采用双重锁实现的单例:

     1     public class Singleton
    2 {
    3 private static readonly object syncObj = new object();
    4 private static Singleton instance;
    5 private Singleton() { }
    6
    7 public static Singleton GetInstance
    8 {
    9 get
    10 {
    11 if (null == instance)
    12 {
    13 lock (syncObj)
    14 {
    15 if (null == instance)
    16 {
    17 instance = new Singleton();
    18 }
    19 }
    20 }
    21 return instance;
    22 }
    23 }
    24 }

    这样实现总该完美了吧,线程安全、延迟加载、效率都没有问题。但是如此写法稍显臃肿,就仅仅为了实现一个单例,搞了这么大一串括号,还为此引入了一个syncObj对象,还有更好的实现方式吗?

    五、【结论】采用原子操作实现的单例:

     1     public class Singleton
    2 {
    3 private static Singleton instance;
    4 private Singleton() { }
    5
    6 public static Singleton GetInstance
    7 {
    8 get
    9 {
    10 if (null == instance)
    11 {
    12 System.Threading.Interlocked.CompareExchange(ref instance, new Singleton(), null);
    13 }
    14 return instance;
    15 }
    16 }
    17 }

    这种写法可以解决以上提到的所有问题,唯一需要提醒一点的是,在调用原子操作之前的判断语句是必不可少的,因为一旦执行CompareExchange方法必然会调用Singleton类型的构造函数,虽然不会引发多个instance对象的问题,但是会造成性能损失,如果构造函数耗时过长,影响将更为严重,所以在调用原子操作之前,先进性单例的判断,就能解决以上问题。

  • 相关阅读:
    函数
    函数
    day---07 文件的操作
    作业9 DFA最小化,语法分析初步
    作业8 非确定的自动机NFA确定化为DFA
    作业7 正规式到正规文法与自动机
    作业6 正规文法与正规式
    作业5 词法分析程序的设计与实现
    作业四 文法和语言总结与梳理
    作业三 语法树,短语,直接短语,句柄
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2238603.html
Copyright © 2011-2022 走看看