您好我一直在使用单例模式,但我无法理解以下代码是如何线程安全的: -
public class ThreadSafeSingleton
{
private ThreadSafeSingleton()
{
}
public static ThreadSafeSingleton Instance
{
get { return Nested.instance; }
}
private class Nested
{
static Nested()
{
}
internal static readonly ThreadSafeSingleton instance = new ThreadSafeSingleton();
}
}
有人可以解释一下吗?干杯:)
答案 0 :(得分:3)
CLR只执行一次静态构造函数。它被指定这样做。因此,instance
正在初始化一次。这使得这个线程安全。
如何实现线程安全是一个实现细节。
答案 1 :(得分:0)
请参阅以下针对线程安全单例实现的实现。
此外,您可以使用此question有用。它提供双锁定螺纹安全性,不会影响性能。
查找静态here
的参考找到参考here
以下代码不是线程安全的。两个不同的线程都可以评估测试if(instance == null)并发现它是真的,然后两个创建实例,这违反了单例模式。请注意,实际上可能已经在计算表达式之前创建了实例,但是内存模型不保证其他线程可以看到实例的新值,除非已经传递了合适的内存屏障。
不是线程安全的单例
// Bad code! Do not use!
public sealed class Singleton
{
private static Singleton instance=null;
private Singleton()
{
}
public static Singleton Instance
{
get
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
线程安全实现:
公共密封班Singleton { private static Singleton instance = null; private static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
此实现是线程安全的。线程取消对共享对象的锁定,然后在创建实例之前检查是否已创建实例。这会解决内存障碍问题(因为锁定确保在获取锁之后逻辑上发生所有读取,并且解锁确保在锁定释放之前逻辑上发生所有写入)并确保只有一个线程将创建实例(仅作为锁定)一个线程一次可以在代码的那一部分中 - 当第二个线程进入它时,第一个线程将创建实例,因此表达式将计算为false)。不幸的是,每次请求实例时都会获得锁定,因此性能会受到影响。