.Net4后ConcurrentDictionary替換Dictionary測試
在.NET Framework 4.0中,增加了ConcurrentDictionary。ConcurrentDictionary<TKey, TValue>
繼承自 Dictionary<TKey, TValue>
,因此它支持大部分標準的字典操作,如添加、查找、刪除等。但是,它還提供了一些額外的線程安全方法,比如 TryAdd
, TryUpdate
, TryRemove
等。
前言
Dictionary<TKey, TValue>
1、泛型類提供了從一組鍵到一組值的映射。通過鍵來檢索值的速度是非??斓?,這是因為 Dictionary<TKey,TValue> 類是作為一個哈希表來實現(xiàn)的。檢索速度取決于為 TKey 指定的類型的哈希算法的質(zhì)量。
2、TValue可以是值類型,數(shù)組,類或其他。
3、一個類的實例里,有個屬性是個字典,我們不加考慮的會用Dictionary,而當這個屬性被提升為static靜態(tài)的(類級別的)時候,我們就要考慮它的線程安全性了,因為它有可能被多個線程同時訪問,當然,如果這個對象是只讀的,也無所謂線程安全,但如果這個屬性是可以被寫的,那就需要把它加鎖了。
4、若允許多個線程對集合執(zhí)行讀寫操作,您必須實現(xiàn)自己的同步,讀寫并行的時候需要加鎖,但是加上鎖性能就會受影響。
ConcurrentDictionary<TKey, TValue>
1、表示可由多個線程同時訪問的鍵/值對的線程安全集合。
2、ConcurrentDictionary是.net4.0推出的一套線程安全集合里的其中一個,和它一起被發(fā)行的還有ConcurrentStack,ConcurrentQueue等類型,它們的單線程版本(線程不安全的,Queue,Stack,Dictionary)。
3、用法同Dictionary很多相同,但是多了一些方法。ConcurrentDictionary 屬于System.Collections.Concurrent 命名空間
ConcurrentDictionary實例測試
在.NET4.0以前,在多線程環(huán)境下如果我們使用Dictionary類,只能自己編碼實現(xiàn)線程同步來保證線程安全,別無他選。在.NET4.0以后微軟替我們開發(fā)了ConcurrentDictionary類,如果你使用字典遇到線程安全的問題,那么就使用ConcurrentDictionary類,不用再考慮“Dictionary+Locks”的問題了。
下面我們對比來看看加鎖后的Dictionary和ConcurrentDictionary的使用情況,是否解決了問題下,性能如何呢?
string res = ""; var concurrentDictionary = new ConcurrentDictionary<int, string>(); var dictionary = new Dictionary<int, string>(); dictionary.TryAdd(1, "aa"); concurrentDictionary.TryAdd(1,""); var sw = new Stopwatch(); sw.Start(); Parallel.For(0, 1000000, i =>//Parallel使用并行循環(huán) { lock (dictionary) { dictionary[i] = new Random().Next(1000, 9999).ToString(); } }); sw.Stop(); Console.WriteLine("加鎖寫入dictionary {0}", sw.Elapsed); //wrinting to dictionary with a lock: 00:00:00.0633939 sw.Restart(); Parallel.For(0, 1000000, i => { concurrentDictionary[i] = new Random().Next(1000, 9999).ToString(); }); sw.Stop(); Console.WriteLine("concurrentdictionary寫入時長 : {0}", sw.Elapsed); sw.Restart(); Parallel.For(0, 1000000, i => { lock (dictionary) { res = dictionary[i]; } }); sw.Stop(); Console.WriteLine("讀取dictionary耗時: {0}", sw.Elapsed); sw.Restart(); Parallel.For(0, 1000000, i => { res = concurrentDictionary[i]; }); sw.Stop(); Console.WriteLine("讀取concurrentdictionary耗時: {0}", sw.Elapsed); Console.ReadLine();
結(jié)果如下
ConcurrentDictionary和Dictionary運行結(jié)果顯示,讀取寫入的效率都是ConcurrentDictionary勝出,完美,也未出現(xiàn)線程安全的問題。注意環(huán)境關(guān)系可能略有差距。據(jù)說在多核多線程的情況下concurrentDictionary將有更好的性能表現(xiàn)。
面試官也可能問Dictionary怎么解決線程安全問題,如果答出使用ConcurrentDictionary一定是加分項。
注意,有網(wǎng)友指出ConcurrentDictionary使用依然會有線程安全問題,樓主目前沒有發(fā)現(xiàn),大家可以自己試一試。
小妙招
tryadd的使用,在字典中添加的時候,集合里已經(jīng)包含了指定的key,Add方法會出錯,拋出異常,如果使用tryadd就會避免這個問題,添加失敗會返回false。
dictionary.TryAdd(1, "aa"); concurrentDictionary.TryAdd(1,"");
注意ConcurrentDictionary只支持TryAdd,普通Dictionary的TryAdd和Add都支持。
到此這篇關(guān)于.Net4后ConcurrentDictionary替換Dictionary測試的文章就介紹到這了,更多相關(guān).Net4后ConcurrentDictionary替換Dictionary內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MVC+EasyUI+三層新聞網(wǎng)站建立 建站準備工作(一)
這篇文章主要為大家詳細介紹了MVC+EasyUI+三層新聞網(wǎng)站建立的第一篇,建站的準備工作,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07Entity Framework Core延遲加載(懶加載)用法
這篇文章介紹了Entity Framework Core延遲加載(懶加載)的使用方式,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-02-02asp.net導(dǎo)出excel數(shù)據(jù)的常見方法匯總
這篇文章主要介紹了asp.net導(dǎo)出excel數(shù)據(jù)的常見方法,實例匯總了數(shù)據(jù)導(dǎo)出的常見的方法以及相關(guān)的注意事項,是非常實用的技巧,需要的朋友可以參考下2014-10-10Windows Server 2012 R2 Standard搭建ASP.NET Core環(huán)境圖文教程
這篇文章主要介紹了Windows Server 2012 R2 Standard搭建ASP.NET Core環(huán)境圖文教程,需要的朋友可以參考下2016-07-07asp.net 從POST的數(shù)據(jù)流中提取參數(shù)和文件
按理,F(xiàn)orm提交的數(shù)據(jù),無論是application/x-www-form-urlencoded還是multipart/form-data(有附件時),都可在服務(wù)端通過Request.Form["name"]和Request.Files["name"]獲取到參數(shù)和上傳的文件。2010-02-02