posts - 9,  comments - 50,  trackbacks - 0

    最近在 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;
                }

            }

        }

    }

0
0
(请您对文章做出评价)
« 上一篇:.Net 下信号量(Semaphore)的一种实现
» 下一篇:ASP.Net应用程序的多进程模型
posted on 2006-02-17 00:06 录一事流 阅读(2351) 评论(10)  编辑 收藏 所属分类: 多线程编程技术