.Net4后ConcurrentDictionary替换Dictionary测试

 更新时间:2025年05月24日 09:10:21   作者:子丶不语  
在.NET Framework 4.0中,增加了ConcurrentDictionary,ConcurrentDictionary<TKey, TValue> 继承自 Dictionary<TKey, TValue>,因此它支持大部分标准的字典操作,如添加、查找、删除等,但是,它还提供了一些额外的线程安全方法,比如 TryAdd, TryUpdate, TryRemove 等

在.NET Framework 4.0中,增加了ConcurrentDictionary。ConcurrentDictionary<TKey, TValue> 继承自 Dictionary<TKey, TValue>,因此它支持大部分标准的字典操作,如添加、查找、删除等。但是,它还提供了一些额外的线程安全方法,比如 TryAddTryUpdateTryRemove 等。

前言

Dictionary<TKey, TValue>

1、泛型类提供了从一组键到一组值的映射。通过键来检索值的速度是非常快的,这是因为 Dictionary<TKey,TValue> 类是作为一个哈希表来实现的。检索速度取决于为 TKey 指定的类型的哈希算法的质量。

2、TValue可以是值类型,数组,类或其他。

3、一个类的实例里,有个属性是个字典,我们不加考虑的会用Dictionary,而当这个属性被提升为static静态的(类级别的)时候,我们就要考虑它的线程安全性了,因为它有可能被多个线程同时访问,当然,如果这个对象是只读的,也无所谓线程安全,但如果这个属性是可以被写的,那就需要把它加锁了。

4、若允许多个线程对集合执行读写操作,您必须实现自己的同步,读写并行的时候需要加锁,但是加上锁性能就会受影响。

ConcurrentDictionary<TKey, TValue>

1、表示可由多个线程同时访问的键/值对的线程安全集合。

2、ConcurrentDictionary是.net4.0推出的一套线程安全集合里的其中一个,和它一起被发行的还有ConcurrentStack,ConcurrentQueue等类型,它们的单线程版本(线程不安全的,Queue,Stack,Dictionary)。

3、用法同Dictionary很多相同,但是多了一些方法。ConcurrentDictionary 属于System.Collections.Concurrent 命名空间

ConcurrentDictionary实例测试

在.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(0, 1000000, i =>//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

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

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

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

小妙招

tryadd的使用,在字典中添加的时候,集合里已经包含了指定的key,Add方法会出错,抛出异常,如果使用tryadd就会避免这个问题,添加失败会返回false。

dictionary.TryAdd(1, "aa");
 concurrentDictionary.TryAdd(1,"");

注意ConcurrentDictionary只支持TryAdd,普通Dictionary的TryAdd和Add都支持。

到此这篇关于.Net4后ConcurrentDictionary替换Dictionary测试的文章就介绍到这了,更多相关.Net4后ConcurrentDictionary替换Dictionary内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MVC+EasyUI+三层新闻网站建立 建站准备工作(一)

    MVC+EasyUI+三层新闻网站建立 建站准备工作(一)

    这篇文章主要为大家详细介绍了MVC+EasyUI+三层新闻网站建立的第一篇,建站的准备工作,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • .NET Core 特性(Attribute)底层原理解析

    .NET Core 特性(Attribute)底层原理解析

    Attribute不仅仅局限于C#中,在整个.NET框架中都提供了非常大的拓展点,任何地方都有Attribute的影子,这篇文章主要介绍了.NET Core 特性(Attribute)底层原理,本文给大家介绍的非常详细,需要的朋友可以参考下
    2024-11-11
  • Entity Framework Core延迟加载(懒加载)用法

    Entity Framework Core延迟加载(懒加载)用法

    这篇文章介绍了Entity Framework Core延迟加载(懒加载)的使用方式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • 关于.Net 6 添加NLog的方法

    关于.Net 6 添加NLog的方法

    .Net项目中关于日志的组件还是很多的,包括log4net,Nlog,以及.net core 框架自带的Logging,今天就简单介绍一下Nlog,对.Net 6 添加NLog相关知识感兴趣的朋友一起看看吧
    2022-01-01
  • asp.net导出excel数据的常见方法汇总

    asp.net导出excel数据的常见方法汇总

    这篇文章主要介绍了asp.net导出excel数据的常见方法,实例汇总了数据导出的常见的方法以及相关的注意事项,是非常实用的技巧,需要的朋友可以参考下
    2014-10-10
  • 如何为asp.net core添加protobuf支持详解

    如何为asp.net core添加protobuf支持详解

    这篇文章主要给大家介绍了关于如何为asp.net core添加protobuf支持的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-02-02
  • 深入理解.NET对象的内存布局

    深入理解.NET对象的内存布局

    在.NET中,理解对象的内存布局是非常重要的,这将帮助我们更好地理解.NET的运行机制和优化代码,本文将介绍.NET中的对象内存布局,感兴趣的可以了解一下
    2023-08-08
  • ASP.NET使用正则表达式屏蔽垃圾信息

    ASP.NET使用正则表达式屏蔽垃圾信息

    找资料,看看如何实现使用正则表达式屏蔽垃圾信息,找来找去找出来的都不怎么好,有不详细的,有代码缺失的。最后还是找到了微软,先摘过来,大概思路已经有了,只需把下面微软给的样例代码修改一下即可,具体能不能行还不知道,先睡一觉,起来再慢慢研究。
    2008-09-09
  • Windows Server 2012 R2 Standard搭建ASP.NET Core环境图文教程

    Windows Server 2012 R2 Standard搭建ASP.NET Core环境图文教程

    这篇文章主要介绍了Windows Server 2012 R2 Standard搭建ASP.NET Core环境图文教程,需要的朋友可以参考下
    2016-07-07
  • asp.net 从POST的数据流中提取参数和文件

    asp.net 从POST的数据流中提取参数和文件

    按理,Form提交的数据,无论是application/x-www-form-urlencoded还是multipart/form-data(有附件时),都可在服务端通过Request.Form["name"]和Request.Files["name"]获取到参数和上传的文件。
    2010-02-02

最新评论