看这么几句解释(英文原帖):

private static void ConcurrentDictionary()
{
var dict = new ConcurrentDictionary<int, string>();
ThreadPool.QueueUserWorkItem(LongGetOrAdd(dict, ));
ThreadPool.QueueUserWorkItem(LongGetOrAdd(dict, ));
} private static WaitCallback LongGetOrAdd(ConcurrentDictionary<int, string> dict, int index)
{
return o => dict.GetOrAdd(index,i =>
{
Console.WriteLine("Adding!");
Thread.SpinWait(); return i.ToString();
}
);
}

1) threadA calls GetOrAdd, finds no item and creates a new item to Add by invoking the valueFactory delegate.

线程A调用GetOrAdd,发现数据不存在并创建了一条新数据,准备调用委托方法添加数据

2) threadB calls GetOrAdd concurrently, its valueFactory delegate is invoked and it arrives at the internal lock before threadA, and so its new key-value pair is added to the dictionary.

线程B现在也在调用GetOrAdd方法,它的委托被调用了,比线程A先进入GetOrAdd内部的锁,因此它创建的键值对被添加到dict中了

3) threadA’s user delegate completes, and the thread arrives at the lock, but now sees that the item exists already

线A的委托执行完成了,并且也获得了GetOrAdd的锁,但是现在发现相关数据已经存在了

4) threadA performs a "Get", and returns the data th at was previously added by threadB.

线程A执行“Get”,返回之前被线程B添加的数据

不止这个英文原帖,好多国内的帖子都在说这个问题。

然而我觉得这并不是个问题,这最多是一个编程时需要注意的事项,微软的这个设计是合理的:ConcurrentDictionary没有理由也没有职责去把外部代码加锁,外部代码的同步应该由

外部控制。回头看看上面的解释,我们发现只不过是传递给ConcurrentDictionary的委托被执行了不止一次,但数据仍然只添加了一次,ConcurrentDictionary已经完全履行了自己的职责,而且MSDN也作了相关的说明(事实上,上面的四句英文也来自MSDN):

The user delegate that is passed to these methods is invoked outside of the dictionary's internal lock. (This is done to prevent unknown code from blocking all threads.)

传递进来的用户委托在字典内部锁的外面调用,这么做是为了防止阻塞所有相关线程,具体参考MSDN

都说ConcurrentDictionary<TKey, TValue>有陷阱的更多相关文章

  1. 线程安全集合 ConcurrentDictionary<TKey, TValue> 类

    ConcurrentDictionary<TKey, TValue> 类 [表示可由多个线程同时访问的键/值对的线程安全集合.] 支持 .NET Framework 4.0 及以上. 示例 ...

  2. C#字典 Dictionary<Tkey,Tvalue> 之线程安全问题 ConcurrentDictionary<Tkey,Tvalue> 多线程字典

    ConcurrentDictionary<Tkey,Tvalue>  Model #region 程序集 mscorlib, Version=4.0.0.0, Culture=neutra ...

  3. .net源码分析 - ConcurrentDictionary<TKey, TValue>

    List源码分析 Dictionary源码分析 ConcurrentDictionary源码分析 继上篇Dictionary源码分析,上篇讲过的在这里不会再重复 ConcurrentDictionar ...

  4. ConcurrentDictionary<TKey, TValue>的AddOrUpdate方法

    https://msdn.microsoft.com/zh-cn/library/ee378665(v=vs.110).aspx 此方法有一共有2个,现在只讨论其中一个 public TValue A ...

  5. c# 扩展方法奇思妙用基础篇五:Dictionary<TKey, TValue> 扩展

    Dictionary<TKey, TValue>类是常用的一个基础类,但用起来有时确不是很方便.本文逐一讨论,并使用扩展方法解决. 向字典中添加键和值 添加键和值使用 Add 方法,但很多 ...

  6. “线程安全的” Dictionary(TKey,TValue)

    这是一篇翻译,专门介绍Dictionary线程安全问题,原文网址如下 http://www.grumpydev.com/2010/02/25/thread-safe-dictionarytkeytva ...

  7. .net源码分析 – Dictionary<TKey, TValue>

    接上篇:.net源码分析 – List<T> Dictionary<TKey, TValue>源码地址:https://github.com/dotnet/corefx/blo ...

  8. .NET中Dictionary<TKey, TValue>浅析

    .NET中Dictionary<TKey, Tvalue>是非常常用的key-value的数据结构,也就是其实就是传说中的哈希表..NET中还有一个叫做Hashtable的类型,两个类型都 ...

  9. .net学习笔记----有序集合SortedList、SortedList<TKey,TValue>、SortedDictionary<TKey,TValue>

    无论是常用的List<T>.Hashtable还是ListDictionary<TKey,TValue>,在保存值的时候都是无序的,而今天要介绍的集合类SortedList和S ...

随机推荐

  1. 百度bae定时任务使用方法

    最近想做个定时执行某些请求的任务,因为不是java的,不能有常住内存的控制,php不知百度bae云怎么做,找了很久终于被我找到了 https://cloud.baidu.com/doc/BAE/GUI ...

  2. css3太极图效果+自动旋转

    主要使用border-radius属性实现圆,半圆,定位坐标覆盖部分模块. 半圆: width: 50%; height: 100%; border-radius:100% 0 0 100% /50% ...

  3. WCF学习笔记(基于REST规则方式)

    一.WCF的定义 WCF是.NET 3.0后开始引入的新技术,意为基于windows平台的通讯服务. 首先在学习WCF之前,我们也知道他其实是加强版的一个面向服务(SOA)的框架技术. 如果熟悉Web ...

  4. Interface的多层继承

    我有一段如下代码,定义一个接口iInterface,cBase实现iInterface,cChild继承cBase,UML为 预期是想要cBase.F()的执行逻辑,同时需要cChild的返回值,所以 ...

  5. Siverlight网页应用程序中WCF通信注意事项

    最近刚刚接触WCF通信,功能就是客户端点击按钮后,服务器端返回一个随机数字.在VS2010中调试的时候,通信都正常,但发布到IIS7中就没反应了,经过几天的摸索,发现WCF的配置要注意以下两点: 1. ...

  6. uCGUI窗口重绘代码分析

    一.概述 µC/GUI的窗口重绘是学习者理解窗口工作原理和应用窗口操作的重点.µC/GUI的窗口重绘引入了回调机制,回调机制可以实现图形系统调用用户的代码,由于图形系统使用了剪切算法,使得屏幕重绘的效 ...

  7. EntityFramework-DBFirst-重新生成后写的验证消失(解决办法)

    1.这是EF生成的类: namespace PMS.DataProvider.EntityFramework { using System; using System.Collections.Gene ...

  8. how to run demo city bars using sencha architect

    1. create a project using city bars template in sencha architect 2. save your project name as CityBa ...

  9. ios音频视频资料--备用

    视频播放 MediaPlayer.framework MPMoviePlayerViewController VS MPMoviePlayerController MPMoviePlayerViewC ...

  10. 使用代理下载Android SDK

    hx.gy:1080是红杏公益服务器,方便科学工作者访问一些常用的科学网站. 在Android SDK Manager中选择[Tools]->[Options],如下设置: HTTP Proxy ...