最近在 Review 代码的时候,发现大量类似如下风格的单件(Singleton)类:

    /// <summary>
    
/// 线程不安全的 Singleton
    
/// </summary>

    public class Singleton
    
{
        
static private Singleton instance;
        
        
private Singleton()
        
{
            
//
            
// TODO: Add constructor logic here
            
//
        }


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

        }

    }

    乍一看还很经典,但细一推敲,却发现了问题:
    
    当多个线程同时调用 Singleton.Instance 属性的时候,每个线程都检测到 instance == null 为真,于是每个都会傻乎乎的创建一个新实例.这将导致最先创建的实例实效,只有最后创建的实例被保存在静态的 instance 中.虽然这在大多数情况下不会引发大问题,但一旦构造函数中有比较耗时的操作,则会造成程序逻辑上的错误.而这些通常都是隐藏得很深,而且很难复现的超级大Bug .所以,要小心哪,同志们!

    为了避免这种问题,我采用了下面的代码:

    /// <summary>
    
/// 线程安全的 Singleton
    
/// </summary>

    public class ThreadSafeSingleton
    
{
        
static private ThreadSafeSingleton instance;
        
static private object syncObj = new object(); //用于线程同步

        
private ThreadSafeSingleton()
        
{
            
//
            
// TODO: Add constructor logic here
            
//
        }


        
static public ThreadSafeSingleton Instance
        
{
            
get
            
{
                
lock( syncObj )  //使用 Monitor 同步
                {
                    
if( instance == null )
                        instance 
= new ThreadSafeSingleton();
                    
return instance;
                }

            }

        }

    }

posted on 2006-02-17 00:06  录一事流  阅读(2810)  评论(10编辑  收藏  举报