C#下的单例实现

关于单例的三种实现方法, 最普通的一种:

关于单例的三种实现方法, 最普通的一种:

using System; 
public class Singleton 

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

这种方案在.Net下面是线程不安全的,每个线程进来会创建不同的类型实例.

下面是一种在.Net公共语言运行环境下的线程安全单例实现模式:
public sealed class Singleton 

   
private static readonly Singleton instance = new Singleton(); 
   
private Singleton(){} 
   
public static Singleton Instance 
   { 
      
get  
      { 
         
return instance;  
      } 
   } 
}
它是依靠公共语言运行时的能力来构造的线程安全模式,在别的语言环境中是不适用的.

基于此加上.Net对泛型的支持,我们可以做一个通用的泛型单例Provider, 代码如下:

    
public class SingletonProvider<T> where T : new()
    {
        SingletonProvider() { }

        
public static T Instance
        {
            
get { return SingletonCreator.instance; }
        }

        
class SingletonCreator
        {
            
static SingletonCreator() { }
            
internal static readonly T instance = new T();
        }
    } 

在此应用下,单例的实例由CLR保证只在首次引用它时才会被创建.

当它不能满足需要时比如你需要在构造函数中做一些其它的操作完成初始化的话, 那么就可以考虑使用Double
-checked locking模式来实现
一个线线程安全的单例:
using System; 
public sealed class Singleton 

   
private static volatile Singleton instance; 
   
private static object syncRoot = new Object(); 
   
private Singleton() {} 
   
public static Singleton Instance 
   { 
      
get  
      { 
         
if (instance == null)  
         { 
            
lock (syncRoot)  
            { 
               
if (instance == null)  
                  instance 
= new Singleton(); 
            } 
         } 
         
return instance; 
      } 
   } 


需要注意的时,这里锁定的是syncRoot,而不是本身,这可以避免产生死锁. 
在其它的语言环境中,Double
-Checked Locking不一定能正常工作,这是由于编译器本身的问题产生的, 所以上面的实现方法

并不一定适用于其它的语言环境,具体的问题在这篇文章中有一些涉及: http:
//www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

这种方案在.Net下面是线程不安全的,每个线程进来会创建不同的类型实例.

下面是一种在.Net公共语言运行环境下的线程安全单例实现模式:

public sealed class Singleton
{
   
private static readonly Singleton instance = new Singleton();
   
private Singleton(){}
   
public static Singleton Instance
   {
      
get 
      {
         
return instance; 
      }
   }
}


它是依靠公共语言运行时的能力来构造的线程安全模式,在别的语言环境中是不适用的.

基于此加上.Net对泛型的支持,我们可以做一个通用的泛型单例Provider, 代码如下:

    public class SingletonProvider<T> where T : new()
    {
        SingletonProvider() { }

        
public static T Instance
        {
            
get { return SingletonCreator.instance; }
        }

        
class SingletonCreator
        {
            
static SingletonCreator() { }
            
internal static readonly T instance = new T();
        }
    }


在此应用下,单例的实例由CLR保证只在首次引用它时才会被创建.

当它不能满足需要时比如你需要在构造函数中做一些其它的操作完成初始化的话, 那么就可以考虑使用Double-checked locking模式来实现
一个线线程安全的单例:

using System;
public sealed class Singleton
{
   
private static volatile Singleton instance;
   
private static object syncRoot = new Object();
   
private Singleton() {}
   
public static Singleton Instance
   {
      
get 
      {
         
if (instance == null
         {
            
lock (syncRoot) 
            {
               
if (instance == null
                  instance 
= new Singleton();
            }
         }
         
return instance;
      }
   }
}


需要注意的时,这里锁定的是syncRoot,而不是本身,这可以避免产生死锁.
在其它的语言环境中,Double-Checked Locking不一定能正常工作,这是由于编译器本身的问题产生的, 所以上面的实现方法

并不一定适用于其它的语言环境,具体的问题在这篇文章中有一些涉及: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

posted on 2007-09-20 13:38  沙加  阅读(1545)  评论(2编辑  收藏  举报

导航