【问题标题】:Thread-safety considerations with IDictionary and ConcurrentDictionaryIDictionary 和 ConcurrentDictionary 的线程安全注意事项
【发布时间】:2017-10-30 16:37:44
【问题描述】:

这个问题主要是学术性的 - 我知道这不一定是实用代码。

考虑一下这段代码,其中线程安全是一个问题:

// In the constructor
IDictionary<string, string> myDictionary = new ConcurrentDictionary<string, string>();

...

// Elsewhere in the class
myDictionary.Add("foo", "bar");

我的总体问题:从并发的角度来看这是如何处理的?

这会被认为是线程安全的吗?如果是,为什么?我问是因为(已知的)线程安全方法是AddOrUpdate - 我无法使用IDictionary 访问它。 CLR 是否“足够聪明”知道这里发生了什么?我在这里是否缺少继承属性,.Add 调用是否可以突变为 .AddOrUpdate 调用“幕后”?

【问题讨论】:

    标签: c# .net concurrency clr


    【解决方案1】:

    CLR 在这里不相关。 ConcurrentDictionary 隐式实现了接口IDictionary&lt;TKey, TValue&gt;,你可以看到它对IDictionary.Add here 做了什么:

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    {
         if (!TryAdd(key, value))
         {
              throw new ArgumentException(GetResource("ConcurrentDictionary_KeyAlreadyExisted"));
        }
    }
    

    因此它会调用TryAddConcurrentDictionary 的“安全”方法),如果无法添加密钥 - 会抛出异常,即具有该密钥的条目已经存在。

    它仍然是“线程安全的”,因为您不会有讨厌的副作用,您将使用常规字典并从多个线程添加项目。如果您为此类异常做好准备 - 您可以安全地将带有 Add 的项目从多个线程添加到此类字典中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多