一、饿汉式(Eager Initialization)

类加载时就创建实例

实现方式

1
2
3
4
5
6
7
8
9
10
11
public sealed class Singleton
{
// 类加载时就创建实例
private static readonly Singleton _instance = new Singleton();

// 私有构造函数,防止外部创建
private Singleton() { }

// 全局访问点
public static Singleton Instance => _instance;
}

优点

天生线程安全(CLR 保证静态初始化线程安全)
实现简单
没有锁开销

缺点

即使不使用,也会创建实例
可能浪费资源
适用场景
单例对象占用资源小
必然会被使用

不在意提前初始化

懒汉式(Lazy Initialization)

第一次使用时才创建实例

非线程安全版本(不推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public sealed class Singleton
{
private static Singleton _instance;

private Singleton() { }

public static Singleton Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}

多线程下可能创建多个实例

加锁版本(线程安全)

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

private Singleton() { }

public static Singleton Instance
{
get
{
lock (_lock)
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
}

问题:

每次访问都会加锁
性能较差

双重检查锁(推荐)

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

private Singleton() { }

public static Singleton Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
}

优点

线程安全
只有第一次创建时才加锁
性能较好