• 单例模式


    前言

      单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    一、简单模式

      

     1     public class Singleton1
     2     {
     3         private static Singleton1 instance;
     4         //构造私有,不能创建实例
     5         private Singleton1()
     6         {
     7 
     8         }
     9         //获得笨类实例的唯一全局访问点
    10         public static Singleton1 GetInstance()
    11         {
    12             if (instance == null)
    13             {
    14                 instance = new Singleton1();
    15             }
    16             return instance;
    17         }
    18     }

    二、多线程保护模式

      lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),知道该对象被释放。

     1     //多线程时的单例
     2     public class Singleton2
     3     {
     4         private static Singleton2 instance;
     5         //程序运行时创建一个静态只读的进程辅助对象
     6         private static readonly object syncRoot = new object();
     7         //构造私有,不能创建实例
     8         private Singleton2()
     9         {
    10 
    11         }
    12         //获得笨类实例的唯一全局访问点
    13         public static Singleton2 GetInstance()
    14         {
    15             //在同一时刻加了锁的那部分程序只有一个线程可以进入
    16             lock (syncRoot)
    17             {
    18                 if (instance == null)
    19                 {
    20                     instance = new Singleton2();
    21                 }
    22             }
    23             return instance;
    24         }
    25     }

      这样每次调用GetInstance方法时都需要lock,会影响性能,所以有了下面的双重锁。

    三、双重锁

      当instance为null并且同时有两个线程调用GetInstance()方法时,他们讲都可以通过第一重instance == null的判断。然后由于lock机制,这两个线程则只有一个进入,另一个在lock那里排队等候,必须要其中的一个进入并出来后,另外一个才能进入。

      如果没有第二重instance == null的判断,则第一个线程创建了实例,而第二个线程还可以继续创建实例。

      

     1     public class Singleton3
     2     {
     3         private static Singleton3 instance;
     4         //程序运行时创建一个静态只读的进程辅助对象
     5         private static readonly object syncRoot = new object();
     6         //构造私有,不能创建实例
     7         private Singleton3()
     8         {
     9 
    10         }
    11         //获得笨类实例的唯一全局访问点
    12         public static Singleton3 GetInstance()
    13         {
    14             //先判断实例是否存在,不存在再加锁处理
    15             if (instance == null)
    16             {
    17                 //在同一时刻加了锁的那部分程序只有一个线程可以进入
    18                 lock (syncRoot)
    19                 {
    20                     if (instance == null)
    21                     {
    22                         instance = new Singleton3();
    23                     }
    24                 }
    25             }
    26             return instance;
    27         }
    28     }

    四、静态初始化

      C#与公共语言运行库提供了一种 ‘静态初始化’ 方法,这种方法不需要开发人员显式地编写线程安全代码,即可解决多线程环境下它是不安全的问题。

      

     1     //密封类不能被继承
     2     public sealed class Singleton4
     3     {
     4         //在第一次引用类的任何成员时创建实例。公共语言运行库负责处理变量初始化
     5         private static readonly Singleton4 instance = new Singleton4();
     6 
     7         private Singleton4() { }
     8         public static Singleton4 GetInstance()
     9         {
    10             return instance;
    11         }
    12     }

      

      这种静态初始化的方式在自己被夹在时就将自己实例化,所以被形象地称为饿汉式单例类

      原来的单例 模式是要在第一次被引用时,才会将自己实例化,所以就被称为懒汉式单例类

    总结

      参考数据:大话设计模式

  • 相关阅读:
    基于fis3的组件可视化道路
    前端性能——监控起步
    uploadify使用的一些经验总结
    浏览器加载和渲染HTML的过程(标准定义的过程以及现代浏览器的优化)
    github常见问题【转自百度知道】
    轮播的实现方式
    前端打包构建工具grunt快速入门(大篇幅完整版)
    一些很棒的js代码
    如何高效的编写Verlog HDL——菜鸟版
    基于FPGA的肤色识别算法实现
  • 原文地址:https://www.cnblogs.com/hyunbar/p/9964843.html
Copyright © 2020-2023  润新知