• 大话设计模式-单例模式


    单例模式

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

    通常我们可以让一个全局变量使得一个对象被访问,但他不能防止你实例化多个对象。

    一个最好的办法就是,让类自身负责保存他的唯一实例。

    这个类可以保证没有其他实例可以被窗创建,并且他可以提供一个访问该实例的方法。


    单例模式结构演示

    class Singleton{
        //静态单例成员变量
        private static Singleton instance;
        //私有构造器,使其无法被外界创建实例
        private Singleton() { }
        //静态方法,获取实例,第一次获取时创建实例
        public static Singleton GetInstance(){
            if (instance == null)
                instance = new Singleton();
            return instance;
        }
    }

    单例模式因为单例类封装他唯一的实例,这样他可以严格地控制客户怎样访问它以及何时访问它。即对唯一实例地受控访问。


    多线程时的单例

    lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区。

    如果其他线程试图进入锁定的代码,则他将一直等待,直到该对象被释放。

    private static Singleton instance;
    private static readonly object syncRoot = new object();
    private Singleton() { }
    public static Singleton GetInstance(){
        lock(syncRoot){
            if (instance == null)
                instance = new Singleton();
        }
        return instance;
    }

    之所以再使用一个syncRoot作为lock地参数,是一位加锁时不知道instance实例有没有被创建。

    但是这样每次调用GetInstance方法时都要lock。

    双重锁定

    再加一层instance==null的判断,判断实例是否存在,不存在的情况再进行加锁处理。

    public static Singleton GetInstance(){
        if (instance == null){
            lock (syncRoot){
                if (instance == null)
                    instance = new Singleton();
            }
        }
        return instance;
    }

    之所以内部还需要再判断一次是因为,假如实例还未创建,两个线程通过了第一层。

    第一个线程先进入锁内,创建了实例,如果不加判断,第二个线程就又创建一次实例。


    静态初始化

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

    public sealed class Singleton{
        private static readonly Singleton instance=new Singleton();
        private Singleton() { }
        public static Singleton GetInstance() => instance;
    }

    这种实现和前面的类似,也是解决了全局访问和实例化控制这两个问题,公共静态属性为访问实例提供了一个全局访问点。

    不同的是,它依赖于公共语言运行库来初始化变量。由于构造器时私有的,不能在类本身以为实例化单例类,因此变量引用的是可以在系统中存在的唯一实例。

    这种静态初始化的方法是在自己被加载时就将自己实例化,所以被称为饿汉式单例类

    之前的单例处理模式是要在第一次被引用时才会将自己实例化,被称为懒汉式单例类

  • 相关阅读:
    小清新数论题泛做
    近日模考理数压轴题简记
    带边数的无向连通图计数
    ZJOI2019 简记
    SDOI2019 R2D2 题解
    [补档题解]后缀树节点数
    [BJ United Round 3] 押韵
    高维 DFT 算法(FWT 快速沃尔什变换)
    SDOI2019 R2D1 题解
    LOJ#6713. 「EC Final 2019」狄利克雷 k 次根 加强版
  • 原文地址:https://www.cnblogs.com/errornull/p/10072444.html
Copyright © 2020-2023  润新知