AI实践哪家强?来 AICon, 解锁技术前沿,探寻产业新机! 了解详情
写点什么

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:078826
用户头像

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

关注

评论

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

Golang 中的好代码 VS 烂代码

baiyutang

编码 Go 语言 9月日更

手撸二叉树之二叉搜索树中的众数

HelloWorld杰少

9月日更

全方位解读服务网格(Service Mesh)的背景和概念

xcbeyond

Service Mesh 服务网格 引航计划

为何数据类大项目都会先做盘点??

奔向架构师

数据仓库 数据治理 9月日更

三分钟带你入门-redis-高可用架构之哨兵,大厂Java高级面试题汇总解答

Java 程序员 后端

深入理解Java中的不可变对象(1),面试加分项

Java 程序员 后端

深入理解Java中的不可变对象,这可能是目前最全的

Java 程序员 后端

性能测试中集合点和多阶段问题初探

FunTester

性能测试 接口测试 测试框架 测试开发 FunTester

【LeetCode】有效的括号字符串Java题解

Albert

算法 LeetCode 9月日更

科技的进步会造福人类吗--闲聊科幻

姬翔

9月日更

分享 4 个前端开发必备的 Chrome 扩展

devpoint

SVG chrome扩展 9月日更

【Flutter 专题】49 图解 Flutter 与 Android 原生交互

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 9月日更

写给互联网工程师的5G书 | 1. 简介

俞凡

架构 5G

翻转未来!钢铁之城重添色彩

白洞计划

HTML进阶(三)

Augus

html 9月日更

Vue进阶(幺零八):npm run build 错误 (node:7852) UnhandledPromiseRejectionWarning: CssSyntaxError:xxxx. 解决分析

No Silver Bullet

Vue 9月日更

服务注册与发现的原理和实现

万俊峰Kevin

微服务 服务注册与发现 microservice 服务发现 Go 语言

网络攻防学习笔记 Day133

穿过生命散发芬芳

网络基础 9月日更

linux之chsh命令

入门小站

Linux

深入理解 Java 多线程核心知识:跳槽面试必备,Java算法基础面试题

Java 程序员 后端

深入理解Java虚拟机-虚拟机执行子系统,字节跳动超高难度三面java程序员面经

Java 程序员 后端

常用特殊符号大全

入门小站

工具

写给互联网工程师的5G书 | 0. 前言

俞凡

架构 5G

Redis核心原理与实践--列表实现原理之ziplist结构

binecy

redis 源码分析

一名优秀的技术Leader是如何炼成的?

架构精进之路

管理 技术管理 引航计划 内容合集

OpenSL ES

Changing Lin

9月日更

Parted 创建 GPT 分区

耳东@Erdong

Linux 9月日更 parted 磁盘分区

Context 和 struct

Rayjun

struct Context Go 语言

深入理解JAVA虚拟机原理之垃圾回收器机制(一),Java开发6年了

Java 程序员 后端

数据结构和算法应用

Albert

算法 9月日更

双指针算法之同向双指针

泽睿

Java 数据结构 面试 双指针算法

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