首页 文章详情

C#中ConcurrentDictionary和Dictionary的那些事儿

DotNet NB | 273 2022-06-17 22:33 0 0 0
UniSMS (合一短信)

    在.NET4.0以前,在多线程环境下如果我们使用Dictionary类,只能自己编码实现线程同步来保证线程安全,别无他选。在.NET4.0以后微软替我们开发了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(01000000i =>//Parallel使用并行循环 {     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();

结果如下

ConcurrentDictionary和Dictionary运行结果显示,读取写入的效率都是ConcurrentDictionary胜出,完美,也未出现线程安全的问题。注意环境关系可能略有差距。据说在多核多线程的情况下concurrentDictionary将有更好的性能表现。

面试官也可能问Dictionary怎么解决线程安全问题,如果答出使用ConcurrentDictionary一定是加分项。

注意,有网友指出ConcurrentDictionary使用依然会有线程安全问题,楼主目前没有发现,大家可以自己试一试。

小妙招
tryadd的使用,在字典中添加的时候,集合里已经包含了指定的key,Add方法会出错,抛出异常,如果使用tryadd就会避免这个问题,添加失败会返回false。
 dictionary.TryAdd(1, "aa"); concurrentDictionary.TryAdd(1,"");
注意ConcurrentDictionary只支持TryAdd,普通Dictionary的TryAdd和Add都支持。

推荐阅读:
  API 工程化分享
  我的微软 MVP 之路
【译】ASP.NET Core 6 中的性能改进
【译】.NET 7 预览版 1 中的 ASP.NET Core 更新
【译】C# 11 特性的早期预览

点击下方卡片关注DotNet NB

一起交流学习

▲ 点击上方卡片关注DotNet NB,一起交流学习

请在公众号后台

回复 【路线图】获取.NET 2021开发者路线图
回复 【原创内容】获取公众号原创内容
回复 【峰会视频】获取.NET Conf开发者大会视频
回复 【个人简介】获取作者个人简介
回复 【年终总结】获取作者年终总结
回复 加群加入DotNet NB 交流学习群

长按识别下方二维码,或点击阅读原文。和我一起,交流学习,分享心得。


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter