静态方法和变量中的线程安全性

时间:2016-03-13 06:06:28

标签: c# .net design-patterns thread-safety singleton

我的印象是默认情况下静态初始化是线程安全的。那是对的吗?还要考虑以下单例模式的例子。

public sealed class SingletonDemo
{
    private static readonly SingletonDemo instance = new SingletonDemo();    
    private SingletonDemo()
    {}
    public static SingletonDemo Instance
    {
        get
        {
            return instance;
        }
    }
} 

以上示例线程是否安全?如果是,为什么?如果没有原因?

1 个答案:

答案 0 :(得分:3)

  

我的印象是默认情况下静态初始化是线程安全的。这是对的吗?

是的,在初始化方面 - 除非你使用反射再次调用类型初始化程序等。当然,一次可以有多个线程访问单例,所以你需要确保实例成员是线程安全的。

请注意,使用C#6,代码可以简化为:

public sealed class SingletonDemo
{
    public static SingletonDemo Instance { get; } = new SingletonDemo();    
    private SingletonDemo() {}
}

CLR的类型初始化规则确保:

  • 该类型仅初始化一次
  • 在一个线程中初始化类型时,其他线程试图访问它阻止
  • 类型初始化完成后存在内存障碍,因此在类型初始化完成后访问变量的所有线程都将看到正确的值

使用代码原样,懒惰保证 - 换句话说,即使SingletonDemo从未实际使用过,也可以初始化Lazy<T>(例如,因为方法是调用哪个有条件地使用它,但条件没有被击中)。要使其完全懒惰,您可以使用public sealed class SingletonDemo { public static SingletonDemo Instance { get; } = new SingletonDemo(); private SingletonDemo() {} private static SingletonDemo() {} } 或静态初始值设定项:

declare @a int
set @a=(select count(*) from sales.orders)
print @a


declare @cnt int,@dt datetime

select @cnt=count(*) ,@dt=max(orderdate) from sales.orders