最近在 Review 代码的时候,发现大量类似如下风格的单件(Singleton)类: /** <summary>
/// 线程不安全的 Singleton
/// </summary>
public class Singleton
{
static private Singleton instance;
private Singleton()
{
//
// TODO: Add constructor logic here
//
} static 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 ThreadSafeSingleton Instance
{
get
{
lock( syncObj ) //使用 Monitor 同步
{
if( instance == null )
instance = new ThreadSafeSingleton();
return instance;
}
}
}
}
posted on 2006-02-17 00:06 录一事流 阅读(80) 评论(4) 编辑 收藏 收藏至365Key 所属分类: 多线程编程技术
Feedback
# re: 编写线程安全的单件(Singleton)
2006-02-17 00:47 | lx
static ThreadSafeSingleton Instance
{
get
{
if( instance == null )
{
lock( syncObj ) //使用 Monitor 同步
{
if( instance == null )
instance = new ThreadSafeSingleton();
}
}
return instance;
}
}
回复
# re: 编写线程安全的单件(Singleton)
2006-02-17 08:01 | 补丁
又写一遍:
public class ThreadSafeSingleton
{
private ThreadSafeSingleton()
{
} public static ThreadSafeSingleton Instance = getInstance();
static ThreadSafeSingleton getInstance()
{
return new ThreadSafeSingleton();
}