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