Tzot

We must accept finite disappointment, but we must never lose infinite hope. -- Mattin Luther King
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

定义:

     作为对象的创建模式[GOF95], Singleton模式确保其一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单态类。

2008-09-02_11-20-20

单态类有以下几个特点:

  1. 单态类只能有一个实例。
  2. 单态类必须自己创建自己的这个实例。
  3. 单态类必须给所有其他对象提供这个实例。

以下是单态模式的几个实现方法:

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 

上面这个写法是没有线程安全,当有两个线程同时走到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 }

上面这个写法加了lock (padlock)语句,那就能保证只有一个线程进入并创建唯一的一个实例。但是这个方法有一点不足,就是每次Return之前都要加锁解锁,影响了性能。

3.两次检查

1public 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

这个方法在加锁之前先判断instance 是否为空,这样只有为Null的时候才加锁并创建一个新的实例,这样就能避免了“简单线程安全”写法的性能问题。

4.

1public 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}

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     }