ConcurrentDictionary 是.NET 4.0中在并行和并发编程方面显著加强的基石。可是在对其进行深刻研究以前,让咱们来回顾一下在.NET以前版本中存在的问题。html
.NET中哈希表的第一个版本是System.Collections.Hashtable。尽管它并不是是线程安全的,但在理论上你能够经过简单地调用Hashtable.Synchronized来获得线程安全的封装器。不幸的是,因为这个封装器所使用的方式,它并非真正线程安全的,编程
比方说,你想要检查一个键值是否存在于集合中。若是不存在,那么你就想要执行一个不会重复的操做,在那里会将结果保存。即便ContainsKey 和set_Item两者都分别是线程安全的,也没有一种方式可以直接对它们进行组合。做为替代的方法,你须要采用SyncRoot上的锁,这会推翻你在前面请求同步版本的全部理由。安全
在System.Collections.Concurrent命名空间下,有ConcurrentDictionary, ConcurrentQueue, ConcurrentStack,BlockingCollection。集合定义var list = new BlockingCollection<T>();并发
.NET 2.0引入泛型和System.Collections.Generic.Dictionary的时候,微软仍是没有解决这个问题。开发者须要采用本身的显式的锁。
.NET 3.5没有添加任何技术,可是它确实使得咱们更易于实如今函数式编程方面加强的程序。首先,它取消了定义自定义委托的思想。从那开始,在任何设计得足够好的API上,均可以重用泛型的Action和Func的委托。另外一个优点是将lambda表达式引入到VB中,而且显著提高了它在C#中的表现。结果是,使用这个API,开发者能够很容易地像这样来建立他们本身的同步封装器: 函数式编程
public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
在以前的版本中,开发者须要对锁进行操做,与此不一样的是,在新的ConcurrentDictionary类中的这个方法看起来很容易就能够正确使用。咱们只须要简单地提供一个键值和一个委托,若是键值不存在就会执行委托。因为函数自己是线程安全的,所以一切都应该是原子级的。函数
好吧,就算不是。为了“避免在锁之下执行未知的代码而引起的各类问题”,valueFactory委托没有在锁中执行。所以就可能存在竞争条件,开发者须要确保valueFactory委托只执行可重复的操做。性能
若是你须要这项功能,那么你须要将ConcurrentDictionary类和Lazy类组合。这样作的示例代码包含在AsyncCache类中,它也做为示例被发布了。spa
尽管这个功能随时都会改变,但当前ConcurrentDictionary的实现已经带有不用锁的读取了。为了提高性能,开发者能够提供写线程的估计数目。这会控制着哈希表将使用多少细粒度的锁。 .net
var dictParallelDays = new ConcurrentDictionary<string, string>(); try { System.Threading.Tasks.Parallel.For(0, 35, i => dictParallelDays.TryAdd(DateTime.Now.AddDays(i).ToString("yyyy-MM-dd"), DateTime.Now.AddDays(i + 1).ToString("yyyy-MM-dd"))); } catch (AggregateException ex) { foreach (var single in ex.InnerExceptions) { //logger.Error("HanTingServiceJob AggregateException: " + ex.Message); } } var dictDays = dictParallelDays.AsParallel().OrderBy((data => data.Key)); dictDays.ForEach(data => { string key = data.Key; string value = data.Value; }); //Parallel Parallel.ForEach(dictParallelDays, item => { Logger.Info("key: " + item.Key + " value : " + item.Value); });
你能够从Stephen Toub的博客中学到更多关于ConcurrentDictionary的知识。线程
查看英文原文:ConcurrentDictionary, .NET 4.0’s New Thread-Safe Hashtable
Refer:
C#集合类型大盘点
http://www.cnblogs.com/jesse2013/p/CollectionsInCSharp.html
Synchronizing ConcurrentDictionary
http://www.codeproject.com/Tips/546382/Synchronizing-ConcurrentDictionary
C#/.NET Little Wonders: The ConcurrentDictionary
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/02/17/c.net-little-wonders-the-concurrentdictionary.aspx