ConcurrentDictionary与Dictionary 替换
本文导读: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是否存

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

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 替换的更多相关文章
- ConcurrentDictionary 与 Dictionary
ASP.NET中ConcurrentDictionary是.Net4 增加的,与 Dictionary 最主要区别是, 前者是线程安全的集合,可以由多个线程同时并发读写Key-value. 那么 ...
- ConcurrentDictionary 对决 Dictionary+Locking
在 .NET 4.0 之前,如果我们需要在多线程环境下使用 Dictionary 类,除了自己实现线程同步来保证线程安全之外,我们没有其他选择. 很多开发人员肯定都实现过类似的线程安全方案,可能是通过 ...
- 浅谈ConcurrentDictionary与Dictionary
在.NET4.0之前,如果我们需要在多线程环境下使用Dictionary类,除了自己实现线程同步来保证线程安全外,我们没有其他选择.很多开发人员肯定都实现过类似的线程安全方案,可能是通过创建全新的线程 ...
- ConcurrentDictionary和Dictionary
http://stackoverflow.com/questions/6739193/is-the-concurrentdictionary-thread-safe-to-the-point-that ...
- 用Dictionary替换switch case
用switch case处理一个很长的判断,例如56个民族01代表汉族,02代表藏族,03代表壮族...,当传入数字想获取民族名称时就得写56个case,当传入民族获取背后的数字时,又得再写56个ca ...
- ConcurrentDictionary并发字典知多少?
背景 在上一篇文章你真的了解字典吗?一文中我介绍了Hash Function和字典的工作的基本原理. 有网友在文章底部评论,说我的Remove和Add方法没有考虑线程安全问题. https://doc ...
- 改进ConcurrentDictionary并行使用的性能
上一篇文章“ConcurrentDictionary 对决 Dictionary+Locking”中,我们知道了 .NET 4.0 中提供了线程安全的 ConcurrentDictionary< ...
- ConcurrentDictionary<TKey, TValue>的AddOrUpdate方法
https://msdn.microsoft.com/zh-cn/library/ee378665(v=vs.110).aspx 此方法有一共有2个,现在只讨论其中一个 public TValue A ...
- 1、C#中Hashtable、Dictionary详解以及写入和读取对比
在本文中将从基础角度讲解HashTable.Dictionary的构造和通过程序进行插入读取对比. 一:HashTable 1.HashTable是一种散列表,他内部维护很多对Key-Value键值对 ...
随机推荐
- GitHub学习系列之如何删除那些不打算要的项目(图文详解)
不多说,直接上干货! 1.选择我们要删除的项目: 接下来我们就删除 zlslch下面的这个hello项目.从这个项目的名字中就可以看出来,好像就是为了删除而创建的.点击右上方红框中的Settings. ...
- leetcode — search-in-rotated-sorted-array
/** * Source : https://oj.leetcode.com/problems/search-in-rotated-sorted-array/ * * Created by lverp ...
- curl模拟post json或post xml文件
转自: https://www.cnblogs.com/xiaochina/p/9750851.html 问题描述: Linux用命令模拟接口,对接口判断!post文件xml/json 问题解决: c ...
- 第3章 NFS基本应用
1.1 概述 类似ext家族.xfs格式的本地文件系统,它们都是通过单个文件名称空间(name space)来包含很多文件,并提供基本的文件管理和空间分配功能.而文件是存放在文件系统中(上述名称空间内 ...
- Docker容器Tomcat部署war包
在docker容器中使用tomcat部署war包主要包括四个步骤,创建tomcat容器.上传war包到容器.重启容器.访问应用. 1.创建tomcat容器 使用docker run -d --nam ...
- iOS SQLite详解
这周比较忙,前几天都加班到11点左右,基本都是到家都是12点左右(稍稍的抱怨一下,免费加班,何为免费,就是任何补偿都没有,例如调休,加班薪,餐补等各项福利,是一点都没有呀)因为App要上线了!App上 ...
- [转]Docker版本变化和新版安装
本文转自:http://www.cnblogs.com/Peter2014/p/7704306.html Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE. 社区版 ...
- vue使用element-ui的el-input监听不了回车事件解决
vue使用element-ui的el-input监听不了回车事件,原因应该是element-ui自身封装了一层input标签之后,把原来的事件隐藏了,所以如下代码运行是无响应的: <el-inp ...
- WPF DevExpress ChartControl用法
WPF常用的第三方控件集,DevExpress中ChartControl的使用 下面介绍如何生成Chart界面: <dxc:ChartControl AnimationMode="On ...
- .net反编译的九款神器(转载)
.net反编译的九款神器 转载来源: https://www.cnblogs.com/zsuxiong/p/5117465.html 本人搜集了下8款非常不错的.Net反编译利器: 1.Reflec ...