我总是看到像这样实施的单身人士:
public class Singleton
{
static Singleton instance;
static object obj = new object();
public static Singleton Instance
{
get
{
lock (obj)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
protected Singleton() { }
}
执行它是否有问题:
public class Singleton
{
static readonly Singleton instance = new Singleton();
public static Singleton Instance
{
get { return instance; }
}
protected Singleton() { }
}
?它在第一次实现的同一时刻被初始化,所以我想知道为什么这不是一个流行的解决方案? 它应该也更快,因为不需要条件,锁定并且字段被标记为只读,这将使编译器做一些优化
请不要谈论单身(反)模式本身,请
答案 0 :(得分:7)
该(或任何其他静态)字段的CLR will initialize the field upon the first use。它promises to do so in a thread-safe manner。
你的代码之间的区别在于第一位代码支持线程安全的延迟初始化,而第二位代码不支持。这意味着当您的代码永远不会访问第一个代码的Singleton.Instance
时,将不会创建new Singleton()
。对于第二个类,只要您访问该类的Instance
或(直接或间接)任何其他静态成员,它就会。甚至更糟 - 它may be initialized before that,因为你缺少一个静态构造函数。
支持更短且更易读的代码,因为.NET 4可以使用Lazy<T>
来显着缩短第一个代码块:
public class Singleton
{
static readonly Lazy<Singleton> instance =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance
{
get { return instance.Value; }
}
static Singleton() { }
private Singleton() { }
}
由于Lazy<T>
也promises thread-safety。这将确保new Singleton()
仅被调用一次,并且仅在实际使用Singleton.Instance
时才会被调用。