本文导读:ASP.NET中ConcurrentDictionary是.Net4 增加的,相对于Dictionary的线程安全的集合, ConcurrentDictionary可实现一个线程安全的集合,可以由多个线程同时并发读写Key-value,与Dictionary的区别主要有以下几点

一、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与Dictionary的区别实例

在多线程环境下,下面实例判断Key是否存

 
C# 代码   复制

public class Program

    {
static Dictionary<string, Logger> loggreDic;
static object loggerDicLocker = new object();
public static void Main()
{
loggreDic = new Dictionary<string, Logger>();
for (int i = 0; i < 100; i++)
{
ThreadPool.QueueUserWorkItem(o =>
{
try
{
var logger = GetLogger("AAA");
}
catch (Exception)
{
Console.WriteLine(string.Format("第{0}个线程出现问题", o));
}

}, i);
}
Console.ReadKey();
}

static Logger GetLogger(string cmdId)
{
if (!loggreDic.ContainsKey(cmdId))
{
loggreDic.Add(cmdId, LogManager.GetLogger(string.Format("AAA.{0}", cmdId)));
}
return loggreDic[cmdId];
}
}

在GetLogger的地方做了判断的处理,但是在多线程的时候还是会报 已添加了具有相同键的项 的错误。原因是在Dictionary中加了重复的Key造成的。

解决方法

可以用ConcurrentDictionary 替代Dictionary

 
C# 代码   复制

    public interface IGetLogger

    {
Logger GetLogger(string cmdId);
}

public class ConcurrentDictionaryLogger : IGetLogger
{
ConcurrentDictionary<string, Logger> loggreDic = new ConcurrentDictionary<string, Logger>();
public Logger GetLogger(string cmdId)
{
if (!loggreDic.ContainsKey(cmdId))
{
loggreDic.TryAdd(cmdId, LogManager.GetLogger(string.Format("AAA.{0}", cmdId)));
}
return loggreDic[cmdId];
}
}

public static void Main()
{
IGetLogger conLogger = new ConcurrentDictionaryLogger();

IGetLogger lockerLogger = new LockerDictionaryLogger();

CodeTimer.Time("使用ConcurrentDictionary", 1000000, () =>
{
ThreadPool.QueueUserWorkItem(o =>
{
try
{
var logger = conLogger.GetLogger("AAA");
if (logger == null)
{
Console.WriteLine(string.Format("第{0}个线程获取到的值是 NULL", o));
}
}
catch (Exception ex)
{
Console.WriteLine(string.Format("第{0}个线程出现问题, {1}", o, ex.Message));
}
});
});
}

ConcurrentDictionary与Dictionary 替换的更多相关文章

  1. ConcurrentDictionary 与 Dictionary

    ASP.NET中ConcurrentDictionary是.Net4 增加的,与 Dictionary 最主要区别是, 前者是线程安全的集合,可以由多个线程同时并发读写Key-value.   那么 ...

  2. ConcurrentDictionary 对决 Dictionary+Locking

    在 .NET 4.0 之前,如果我们需要在多线程环境下使用 Dictionary 类,除了自己实现线程同步来保证线程安全之外,我们没有其他选择. 很多开发人员肯定都实现过类似的线程安全方案,可能是通过 ...

  3. 浅谈ConcurrentDictionary与Dictionary

    在.NET4.0之前,如果我们需要在多线程环境下使用Dictionary类,除了自己实现线程同步来保证线程安全外,我们没有其他选择.很多开发人员肯定都实现过类似的线程安全方案,可能是通过创建全新的线程 ...

  4. ConcurrentDictionary和Dictionary

    http://stackoverflow.com/questions/6739193/is-the-concurrentdictionary-thread-safe-to-the-point-that ...

  5. 用Dictionary替换switch case

    用switch case处理一个很长的判断,例如56个民族01代表汉族,02代表藏族,03代表壮族...,当传入数字想获取民族名称时就得写56个case,当传入民族获取背后的数字时,又得再写56个ca ...

  6. ConcurrentDictionary并发字典知多少?

    背景 在上一篇文章你真的了解字典吗?一文中我介绍了Hash Function和字典的工作的基本原理. 有网友在文章底部评论,说我的Remove和Add方法没有考虑线程安全问题. https://doc ...

  7. 改进ConcurrentDictionary并行使用的性能

    上一篇文章“ConcurrentDictionary 对决 Dictionary+Locking”中,我们知道了 .NET 4.0 中提供了线程安全的 ConcurrentDictionary< ...

  8. ConcurrentDictionary<TKey, TValue>的AddOrUpdate方法

    https://msdn.microsoft.com/zh-cn/library/ee378665(v=vs.110).aspx 此方法有一共有2个,现在只讨论其中一个 public TValue A ...

  9. 1、C#中Hashtable、Dictionary详解以及写入和读取对比

    在本文中将从基础角度讲解HashTable.Dictionary的构造和通过程序进行插入读取对比. 一:HashTable 1.HashTable是一种散列表,他内部维护很多对Key-Value键值对 ...

随机推荐

  1. Windows服务器端口绑定证书

    打开IIS:inetmgr 打开服务:ctrl+shift+Esc 查看证书秘钥: 服务器查看https证书绑定: 1) 查看证书 netsh http show sslcert 2) 将证书与端口绑 ...

  2. linux 两个查找工具 locate,find

    linux 中有很多查找工具,今天主要讲解locate,find两个工具. 一.locate 1.性能介绍 查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db 注意 ...

  3. 【mac】ansible安装及基础使用

    安装 环境释放 mac 10.12.5 #more /System/Library/CoreServices/SystemVersion.plist 安装命令 #ruby -e "$(cur ...

  4. Linux查询端口是否被占用的四种方法

    一个面试题,使用三种不同的方法查看8080被哪个进程占用了.通常比较熟悉的方法是netstat和lsof两种,但还有什么方法呢. 1.netstat或ss命令 netstat -anlp | grep ...

  5. “多个单核CPU”与“单个多核CPU”哪种方式性能较强?

    多个单核CPU: 成本更高,因为每个CPU都需要一定的线路电路支持,这样对主板上布局布线极为不便.并且当运行多线程任务时,多线程间通信协同合作也是一个问题.依赖总线的传输,速度较慢,且每一个线程因为运 ...

  6. 第一册:lesson7-8.

    原文:Are you a teacher? A:I am a  new student ,my name is A. B:Nice to meet you,my name is B. A:Are yo ...

  7. ___Jquery多选框的取值及反显数据

    Jquery操作 ------------------------------------------------------ var arr = new Array(); $("input ...

  8. 依然是关于我空间那篇申请的日志《JavaScript axError:Unexpected token ILLEGAL 很简单的代码……》

    接下来要讲的日志现在的标题已经更改为<很简单的代码,但是无法--> 这篇日志地址:http://www.cnblogs.com/herbertchina/p/4475092.html 经过 ...

  9. Netty实战十二之WebSocket

    如果你有跟进Web技术的最新进展,你很可能就遇到过“实时Web”这个短语,这里并不是指所谓的硬实时服务质量(QoS),硬实时服务质量是保证计算结果将在指定的时间间隔内被递交.仅HTTP的请求/响应模式 ...

  10. Hibernate-在Eclipse(Oxygen)中安装Hibernatetools插件

    Eclipse(Luna)中是没有Hibernate插件的,该插件是需要自己进行添加. 在网上找了一下关于如何在Eclipse中安装Hibernatetools插件的方法,很多都是先找到Hiberna ...