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