Singleton

一、单例模式的定义

  确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例,是一种对象创建型模式,有如下3个要点:

  • 只能有一个实例
  • 必须是自行创建这个实例
  • 必须自行向整个系统提供这个实例

二、单例模式的结构

  • 一个类型为自身的静态私有成员变量 - 存储唯一实例

  • 一个私有的构造函数

  • 一个公有的静态成员方法 ,返回唯一实例,对象为自身

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class Singleton
    {
    //静态私有成员变量,存储唯一实例
    private static Singleton _instance = null; 、

    //私有构造函数,保证唯一性
    private Singleton()
    {
    }

    //公有静态方法,返回一个唯一的实例
    public static Singleton GetInstance()
    {
    if (_instance == null)
    {
    _instance = new Singleton();
    }
    return _instance;
    }
    }

三、单例模式的两种书写方法

1.类被加载时就将自己实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton
{
private static Singleton _instance = new Singleton();

private Singleton()
{
}

public static Singleton GetInstance()
{
return _instance;
}
}

2.类在第一次被引用时将自己实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Singleton
{
private static Singleton _instance = null;
private static readonly object syncRoot = new object();

private Singleton()
{
}

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

四、双重锁的运用分析

​ 在上述代码中出现“If - Lock - If”结构模式,即双重检查锁定的双重判断机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
//第一重判断,先判断实例是否存在,不存在再加锁处理
if (_instance == null)
{
//加锁,在某一时刻只允许一个线程访问
lock (syncRoot)
{
//第二重判断: 第一个线程进入Lock中执行创建代码,第二个线程处于排队等待状态,当第二个线程进入Lock后并不知道实例已创建,将会继续创建新的实例
if (_instance == null)
{
_instance = new SingletonClass();
}
}
}

五、单例模式的优缺点

  • 封装了唯一性,可严格控制客户怎么访问及何时访问

  • 内存中只存在一个对象,可节约系统资源,提高系统性能

  • 单例类的扩展不方便

  • 单例类既提供了业务方法,又提供了创建对象的方法,将对象的创建和对象本身的功能耦合在一起