定义:
作为对象的创建模式[GOF95], Singleton模式确保其一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单态类。
单态类有以下几个特点:
- 单态类只能有一个实例。
- 单态类必须自己创建自己的这个实例。
- 单态类必须给所有其他对象提供这个实例。
以下是单态模式的几个实现方法:
1 无线程安全。
1 public sealed class Singleton
2 {
3 static Singleton instance=null;
4
5 Singleton()
6 {
7 }
8
9 public static Singleton Instance
10 {
11 get
12 {
13 if (instance==null)
14 {
15 instance = new Singleton();
16 }
17 return instance;
18 }
19 }
20 }
21
2 {
3 static Singleton instance=null;
4
5 Singleton()
6 {
7 }
8
9 public static Singleton Instance
10 {
11 get
12 {
13 if (instance==null)
14 {
15 instance = new Singleton();
16 }
17 return instance;
18 }
19 }
20 }
21
上面这个写法是没有线程安全,当有两个线程同时走到if (instance==null),并发现都是True,那将会创建两个实例。所以不推荐使用这个方法。
2 简单线程安全
1 public sealed class Singleton
2 {
3 static Singleton instance=null;
4 static readonly object padlock = new object();
5
6 Singleton()
7 {
8 }
9
10 public static Singleton Instance
11 {
12 get
13 {
14 lock (padlock)
15 {
16 if (instance==null)
17 {
18 instance = new Singleton();
19 }
20 return instance;
21 }
22 }
23 }
24 }
2 {
3 static Singleton instance=null;
4 static readonly object padlock = new object();
5
6 Singleton()
7 {
8 }
9
10 public static Singleton Instance
11 {
12 get
13 {
14 lock (padlock)
15 {
16 if (instance==null)
17 {
18 instance = new Singleton();
19 }
20 return instance;
21 }
22 }
23 }
24 }
上面这个写法加了lock (padlock)语句,那就能保证只有一个线程进入并创建唯一的一个实例。但是这个方法有一点不足,就是每次Return之前都要加锁解锁,影响了性能。
3.两次检查
1
public sealed class Singleton
2
{
3
static Singleton instance=null;
4
static readonly object padlock = new object();
5
6
Singleton()
7
{
8
}
9
10
public static Singleton Instance
11
{
12
get
13
{
14
if (instance==null)
15
{
16
lock (padlock)
17
{
18
if (instance==null)
19
{
20
instance = new Singleton();
21
}
22
}
23
}
24
return instance;
25
}
26
}
27
}
28
public sealed class Singleton2
{3
static Singleton instance=null;4
static readonly object padlock = new object();5

6
Singleton()7
{8
}9

10
public static Singleton Instance11
{12
get13
{14
if (instance==null)15
{16
lock (padlock)17
{18
if (instance==null)19
{20
instance = new Singleton();21
}22
}23
}24
return instance;25
}26
}27
}28

这个方法在加锁之前先判断instance 是否为空,这样只有为Null的时候才加锁并创建一个新的实例,这样就能避免了“简单线程安全”写法的性能问题。
4.
1
public sealed class Singleton
2
{
3
static readonly Singleton instance=new Singleton();
4
5
// Explicit static constructor to tell C# compiler
6
// not to mark type as beforefieldinit
7
static Singleton()
8
{
9
}
10
11
Singleton()
12
{
13
}
14
15
public static Singleton Instance
16
{
17
get
18
{
19
return instance;
20
}
21
}
22
}
public sealed class Singleton2
{3
static readonly Singleton instance=new Singleton();4

5
// Explicit static constructor to tell C# compiler6
// not to mark type as beforefieldinit7
static Singleton()8
{9
}10

11
Singleton()12
{13
}14

15
public static Singleton Instance16
{17
get18
{19
return instance;20
}21
}22
}5.
1
2 public sealed class Singleton
3 {
4 Singleton()
5 {
6
7 }
8 public static Singleton Instance
9 {
10 get
11 {
12 return Nested.instance;
13 }
14 }
15
16 class Nested
17 {
18 static Nested()
19 {
20
21 }
22
23 internal static readonly Singleton instance = new Singleton();
24 }
25 }
2 public sealed class Singleton
3 {
4 Singleton()
5 {
6
7 }
8 public static Singleton Instance
9 {
10 get
11 {
12 return Nested.instance;
13 }
14 }
15
16 class Nested
17 {
18 static Nested()
19 {
20
21 }
22
23 internal static readonly Singleton instance = new Singleton();
24 }
25 }


浙公网安备 33010602011771号