设计模式学习笔记之 Singleton 

     Singleton模式是创建型模式的一种,其目的是确保一个Singleton类中只唯一存在的实例,并提供该实例的全局访问点

     对于单线程Singleton模式来说比较简单

   sealed class Singleton
   
{
        
private Singleton() { }
        
private static Singleton mySingleton;
        
public static Singleton GetSingleton
        
{
            
get
            
{
                
if (mySingleton == null)
                
{
                    mySingleton 
= new Singleton();
                }

                
return mySingleton;
            }

        }

   }

     首先 private Singleton() { }  绕过类默认的构造器,使得Singleton的实例只能通过GetSingleton静态属性得到而不能通过在外部 new Singleton() 来得到。在实例化之前判断静态字段 mySingleton是否存在,若不存在则 new Singleton(),通过这种手段来确保 mySingleton是唯一存在的。

     对于多线程来说,可能会因为时间间隔非常近的两次 GetSingleton而得到2个实例,为了应对这种情况,又有一种双锁的方法

    sealed class Singleton
    
{
        
private Singleton() { }
        
private static volatile Singleton mySingleton;
        
private static object helper = new object();
        
public static Singleton GetSingleton
        
{
            
get
            
{
                
if (mySingleton == null)
                
{
                    
lock (helper)
                    
{
                        
if (mySingleton == null)
                        
{
                            mySingleton 
= new Singleton();
                        }

                    }

                }

                
return mySingleton;
            }

        }

    }

     首先实例化一个helper用来辅助型的对象,在判断mySingleton为空之后,为了避免上面所说的情况发生,对helper进行加锁,然后再检查mySingleton是否为空,这样就能保证在多线程状况下也可以唯一实例。volatile关键字是用来防止编译器对代码的调整,以防出现调整时出现的意外。
     WebCast中讲了下面一种非常简练的Singleton

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


     这种写法等同于

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

        
private Singleton() { }
    }

     初始化过程 new  Singleton()被放在静态构造器中,因为静态构造器只会在静态字段初始化之前进行初始化,又因为默认构造器被绕过,因此如果要访问这个静态只读字段,那么静态构造器一定会被执行。.Net构造器也会保证静态初始化过程只会有一个线程执行,不会出现多线程的问题。

    private static void SingletonTest()
    
{
        Singleton singleton1 
= Singleton.mySingleton;
        Singleton singleton2 
= Singleton.mySingleton;
        Console.WriteLine(
object.ReferenceEquals(singleton1, singleton2).ToString());
        Console.ReadLine();
    }

     通过上面程序可以看出singleton1 和 singleton2 指向同一地址,它们都是Singleton唯一实例。

 参考:       MSDN WebCast  C#设计模式纵横谈        李建忠

     回到目录
posted on 2006-09-10 16:11  aiya  阅读(288)  评论(0)    收藏  举报