Singleton单例模式

>>返回《C#常用设计模式》

1. 简介

定义

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

注意

  1. 单例模型下实例化操作应该是类的设计者的责任,而不是使用者的责任。
  2. 在该类中直接提供实例化的方法,保证实例唯一

2. 示例

2.1. 最常见的单例模式

public class Singleton
{
    //保存实例容器
    private static Singleton instance = null;
    //取消默认的public的缺省构造器
    private Singleton() { }
    //实例的出口
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}

2.2. 线程安全的单例模式

public class Singleton
{
    //volatile 它是被设计用来修饰被不同线程访问和修改的变量。
    //如果没有volatile,基本上会导致这样的结果:
    //要么无法编写多线程程序,要么编译器失去大量优化的机会。
    //volatile的作用: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.
    private static volatile Singleton instance = null;

    private static object lockHelper = new object();
    //取消默认的public的构造器
    private Singleton() { }
    //实例的出口
    public static Singleton Instance
    {
        get
        {
            //double check 前面的判断是为了减少后面判断的访问,因为后面的判断会阻塞并发线程
            if (instance == null)
            {
                lock (lockHelper)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
}

2.3. 线程安全且简练的单例模式

利用了静态构造方法是线程安全的。

缺点: 不接受参数

public class Singleton
{
    public static readonly Singleton Instance = new Singleton();
    private Singleton() { }
}

等价于

public class Singleton
{
    public static readonly Singleton Instance;
    static Singleton()
    {
        Instance = new Singleton();
    }
    private Singleton() { }
}

说明:

  1. 静态构造器执行时间:在静态字段初始化之前执行。
  2. 内联初始化编译后会将初始化的内容放到静态构造器内部执行
  3. 静态构造器只能被一个线程执行一次,不可能被多线程执行

2.4. 含参数的单例模式

一般情况下用不到。

public class Singleton
{
    //保存实例容器
    private static Singleton instance;
    //取消默认的public的构造器
    private Singleton(int x,int y) 
    {
        this.x = x;
        this.y = y;
    }
    //实例的出口
    public static Singleton GetInstance(int x, int y) 
    {
        if (instance == null)
        {
            instance = new Singleton(x,y);
        }
        else
        {
            instance.x = x;
            instance.y = y;
        }
        return instance;
    }
    private int x;
    private int y;
}
posted @ 2021-02-09 22:13  大师兄石头  阅读(576)  评论(0编辑  收藏  举报