写点什么

ConcurrentDictionary:.NET 4.0 中新的线程安全的哈希表

  • 2010-01-31
  • 本文字数:1028 字

    阅读完需:约 3 分钟

ConcurrentDictionary 是.NET 4.0 中在并行和并发编程方面显著增强的基石。但是在对其进行深入研究之前,让我们来回顾一下在.NET 之前版本中存在的问题。

.NET 中哈希表的第一个版本是 System.Collections.Hashtable。尽管它并非是线程安全的,但在理论上你可以通过简单地调用 Hashtable.Synchronized 来得到线程安全的封装器。不幸的是,由于这个封装器所使用的方式,它并不是真正线程安全的,

比方说,你想要检查一个键值是否存在于集合中。如果不存在,那么你就想要执行一个不会重复的操作,在那里会将结果保存。即使 ContainsKey 和 set_Item 二者都分别是线程安全的,也没有一种方式能够直接对它们进行组合。作为替代的方法,你需要采用 SyncRoot 上的锁,这会推翻你在前面请求同步版本的所有理由。

当.NET 2.0 引入泛型和 System.Collections.Generic.Dictionary 的时候,微软还是没有解决这个问题。开发者需要采用自己的显式的锁。

.NET 3.5 没有添加任何技术,但是它确实使得我们更易于实现在函数式编程方面增强的程序。首先,它取消了定义自定义委托的思想。从那开始,在任何设计得足够好的 API 上,都可以重用泛型的 Action 和 Func 的委托。另一个优势是将 lambda 表达式引入到 VB 中,并且显著提升了它在 C#中的表现。结果是,使用这个 API,开发者可以很容易地像这样来创建他们自己的同步封装器:

复制代码
public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)

在之前的版本中,开发者需要对锁进行操作,与此不同的是,在新的 ConcurrentDictionary 类中的这个方法看起来很容易就可以正确使用。我们只需要简单地提供一个键值和一个委托,如果键值不存在就会执行委托。由于函数本身是线程安全的,因此一切都应该是原子级的。

好吧,就算不是。为了“避免在锁之下执行未知的代码而引发的各种问题”,valueFactory 委托没有在锁中执行。因此就可能存在竞争条件,开发者需要确保 valueFactory 委托只执行可重复的操作。

如果你需要这项功能,那么你需要将 ConcurrentDictionary 类和 Lazy 类组合。这样做的示例代码包含在 AsyncCache 类中,它也作为示例被发布了。

尽管这个功能随时都会改变,但当前 ConcurrentDictionary 的实现已经带有不用锁的读取了。为了提升性能,开发者可以提供写线程的估计数目。这会控制着哈希表将使用多少细粒度的锁。

你可以从 Stephen Toub 的博客中学到更多关于ConcurrentDictionary 的知识

查看英文原文: ConcurrentDictionary, .NET 4.0’s New Thread-Safe Hashtable

2010-01-31 18:078636
用户头像

发布了 340 篇内容, 共 132.0 次阅读, 收获喜欢 13 次。

关注

评论

发布
暂无评论
发现更多内容

专访北大荆琦:产业前沿进课堂,通过产学合作培养开源贡献者

Lily

Java中的重载和重写的区别

共饮一杯无

Java 10月月更 重载重写

【Ajv】JSON Schema Validator

小鑫同学

前端 Node 10月月更

Qt | 实现动态创建多个Tab页,页中动态创建多个子部件

YOLO.

qt 10月月更 C++

通过linux-PAM实现禁止root用户登陆的方法

京东科技开发者

数据库 Linux 公有云 云主机 linux-PAM

构建工具Gulp-lesson4

小鑫同学

前端 Node 10月月更

20221013

留白的艺术

Vue2.x组件间通信汇总表

小鑫同学

前端 Node 10月月更

Docker下Nacos持久化配置

程序员欣宸

Docker Spring Cloud nacos 10月月更

熬夜整理最近前端面试知识点

loveX001

JavaScript

如何搭建组件库的最小原型

小鑫同学

前端 Node 10月月更

搭建组件库最小原型(支线)

小鑫同学

前端 Node 10月月更

构建工具Gulp-lesson5

小鑫同学

前端 Node 10月月更

打包 Composition API、Vue3

小鑫同学

前端 Node 10月月更

Spring JPA 查询的时候提示错 org.hibernate.TransientObjectException

HoneyMoose

HashSet源码全方位解读

知识浅谈

10月月更

QtCreator配置protobuf环境

中国好公民st

qt Qt Creator 10月月更

Java数组详解

共饮一杯无

Java 数组 10月月更

编程语言中 null 引用的十亿美元错误趣谈

汪子熙

Java JavaScript SAP abap 10月月更

【Java深入学习】线程状态

Geek_65222d

10月月更

正确发送统计数据到服务器

小鑫同学

前端 Node 10月月更

Java基础(四)| 数组及内存分配详解

timerring

Java 数组 内存分配 10月月更

SAP UI5 OData谣言粉碎机:极短时间内发送两个 Odata request,前一个会自动被 cancel 掉吗

汪子熙

JavaScript 前端开发 SAP UI5 ui5 10月月更

Docker load 大镜像(17G) 报错no space left on device

琦彦

Docker 10月月更 Base Device Size

【个人成长】我认为的好的日报

非晓为骁

个人成长 日报

西安交大谢涛:云上做实验,让计算机教学实现质的飞跃

Lily

谈谈前端性能优化-面试版

loveX001

JavaScript

从URL输入到页面展现到底发生什么?

loveX001

JavaScript

Qt | 线程 QThread

YOLO.

c++ qt 10月月更

【愚公系列】2022年10月 Go教学课程 027-深拷贝和浅拷贝

愚公搬代码

10月月更

标签与指标到底有什么区别?

雨果

标签 指标

ConcurrentDictionary:.NET 4.0中新的线程安全的哈希表_.NET_Jonathan Allen_InfoQ精选文章