这可能是基本问题
要在多线程环境中使用单例,我们可以使用锁.请参阅代码段.但为什么我们需要在单件模式中进行双重检查锁定?更多的双重锁定意味着什么?
class singleton
{
private static singleton instance = null;
private static singleton() { }
private static object objectlock = new object();
public static singleton Instance
{
get
{
lock (objectlock) //single - check lock
{
if (instance == null)
{
instance = new singleton();
}
return instance;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
SLa*_*aks 27
Jon Skeet 详细解释了这一点.
锁是昂贵的.
如果对象已经存在,那么取出锁是没有意义的.
因此,您可以在锁外进行第一次检查.
但是,即使在您查看之前该对象不存在,另一个线程也可能在if条件和lock语句之间创建它.
因此,您需要在锁内再次检查.
但是,编写单例的最佳方法是使用static构造函数:
public sealed class Singleton
{
private Singleton()
{
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
多线程单例:使用双重检查锁定的最佳方法
public sealed class Singleton
{
private static volatile Singleton _instance;
private static readonly object InstanceLoker= new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (_instance == null)
{
lock (InstanceLoker)
{
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
使用.Net 4.x和更新版本时,您应尽可能遵循Lazy类,因为此模式与"初始化和发布"选项一起使用.(注意:逆也可用,其中创建不是线程安全的,但实例的发布是通过Publication选项发布的)