ContainsKey线程安全

时间:2009-04-02 17:14:37

标签: c# multithreading dictionary

在以下代码中:

public class StringCache
{
    private readonly object lockobj = new object();

    private readonly Dictionary<int, string> cache = new Dictionary<int, string>();

    public string GetMemberInfo(int key)
    {
        if (cache.ContainsKey(key))
            return cache[key];
        lock (lockobj)
        {
            if (!cache.ContainsKey(key))
                cache[key] = GetString(key);
        }
        return cache[key];
    }

    private static string GetString(int key)
    {
        return "Not Important";
    }
}

1)ContainsKey线程是否安全? IOW,如果在另一个线程向字典中添加内容时执行该方法会发生什么? 2)对于第一个返回缓存[key],是否有可能返回乱码值?

TIA,

MB

5 个答案:

答案 0 :(得分:14)

ContainsKey的固有线程安全性并不重要,因为ContainsKey和&amp;之间没有同步。缓存[键]。

例如:

if (cache.ContainsKey(key))
   // Switch to another thread, which deletes the key.
   return cache[key];

MSDN在这一点上非常清楚:

  

允许访问集合   通过多个线程进行阅读和   写作,你必须实现自己的   同步。

有关详细信息,JaredPar在http://blogs.msdn.com/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx上发布了一篇关于线程安全集合的精彩博客文章。

答案 1 :(得分:6)

不,如果您在尝试阅读时写入值,则ContainsKey不是线程安全的。

是的,您可能会收到无效结果 - 但您可能会首先看到异常。

看看ReaderWriterLockSlim是否锁定了这样的情况 - 它是为了做这种事情而构建的。

答案 2 :(得分:1)

以下是MSDN documentation:

中的内容
  

此类型的公共静态(在Visual Basic中为Shared)成员是线程安全的。不保证任何实例成员都是线程安全的。

     

字典&lt;(Of&lt;(TKey,TValue&gt;)&gt;)   可以支持多个读者   同时,只要   集合未被修改。即使是这样,   通过集合枚举是   本质上不是线程安全的   程序。在罕见的情况下   枚举与写作竞争   访问,集合必须   在整个枚举期间锁定。   允许访问集合   通过多个线程进行阅读和   写作,你必须实现自己的   同步。

如果我正确阅读,我不相信它是线程安全的。

答案 3 :(得分:1)

字典不是线程安全

如果你这么说

  

如果是这种方法会发生什么   在另一个线程执行时执行   在字典中添加内容?

然后我想其他函数也会访问cache。您需要将访问(读取和写入)同步到cache。在所有这些操作中使用锁定对象。

答案 4 :(得分:1)

我认为它不是线程安全的,

我建议通过下面的链接,它显示线程安全字典的实现,或者更好地开发自己的同步。

http://lysaghtn.weebly.com/synchronised-dictionary.html