【问题标题】:Multithreading and static constructor [duplicate]多线程和静态构造函数
【发布时间】:2014-08-27 13:20:49
【问题描述】:

假设我有以下课程:

class Dummy
{
    public static Dictionary<int, int> dict = new Dictionary<int, int>();  // (1)

    static Dummy()   // (2)
    {
        dict.Add(1, 100);
        dict.Add(2, 200);
    }        
}

此类型将由多个线程访问。 (1) 和 (2) 什么时候执行?它们会为每个线程执行吗?会不会出现key重复异常?

【问题讨论】:

  • 参见:stackoverflow.com/a/7105/1336590 - “静态构造函数保证每个应用程序域只运行一次”。还有:msdn.microsoft.com/library/aa645612.aspx
  • 并不是说我认为它会改变线程安全的任何事情(我认为这不是问题),但如果你愿意,你可以写public static Dictionary&lt;int, int&gt; dict = new Dictionary&lt;int, int&gt; { { 1, 100 }, { 2, 200 }, };。那么你就不需要手动编写静态构造函数了。 (仍然会生成一个静态构造函数,所以我猜线程问题不会因此而受到影响,所以这只是你觉得哪个代码更有吸引力的问题。)

标签: c#


【解决方案1】:

每当创建第一个实例时,都会访问它们。没有密钥重复的机会。它们只会发生一次。并且如果静态构造函数在处理过程中发生错误,将不会再被访问。

请参阅下面的 JohnSaunders cmets 了解此调用的原子性。

【讨论】:

  • 它们只会出现一次,但不会以原子方式出现。如果两个线程访问该类型,那么其中一个线程可能会看到dict 只有一个条目的状态,或者就此而言,没有条目。
  • @JohnSaunders 同意。
  • @JohnSaunders 如何解决原子问题?我可以使用 Lazy 初始化吗?
  • @smwikipedia:我不知道Lazy&lt;T&gt; 是否是原子的。您可以通过添加private static object _locker = new object(); 然后添加static Dummy(){lock (_locker){dict.Add(1, 100);dict.Add(2,200);} 来解决您的问题。您也不应该使用公共字段。请改用属性。
  • @JohnSaunders 您是否声称一个线程可以在静态构造函数(例如,在另一个线程上运行)运行结束之前访问该类的静态成员?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
  • 2011-03-01
  • 2010-09-12
  • 2014-03-14
  • 2011-02-20
相关资源
最近更新 更多