阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

枚举并发集合探讨

  • 2008-09-03
  • 本文字数:1288 字

    阅读完需:约 4 分钟

.NET 的并行扩展(Parallel Extensions)包括两个并发集合:堆栈和队列。其他集合类还是按照它们固有的方式工作,但是对于语义的处理依然有一些挥之不去的问题。尤其是当集合在一个线程被编辑,而在另外一个线程被枚举的时候,会发生什么呢?

对于单线程的类,答案是众所周之的,枚举器将抛出一个异常。不过对于并发类来说,在这种情况下应该设定一种规则,提供几种选择。

一种选择是,在枚举开始的时候为现存数据创建一个快照。这种方式在循环的过程中会占用更多的内存,不过快照一旦被创建,就可以被自由地锁定。这种方式下隐含的性能问题很难被预估。

不使用快照,集合还有一组保证措施提供给开发人员。它们中很多都是自相矛盾的,不过在某些条件下它们也都是适合的。

  • 删除的条目总是可读
  • 删除的条目不可再读
  • 如果添加在集合的末尾,那么添加的条目总是可读
  • 如果添加在集合的任何地方,那么添加的条目总是可读
  • 添加的条目总是不可读取
  • 被移动的条目,不能被读取两次
  • 被移动的条目,如果是移动到集合的末尾,那么就能被读取两次
  • 被移动的条目,就算是被移动到集合的开头,也总是可以读取
  • 不超过 N 条的条目就能被读取,而 N 是集合的初始大小。

在给出一个选择范围后, Stephen Toub 向大家征询关于并行扩展的反馈意见

  1. 鉴于在.NET 中已经存在一些标准的集合类了,假如你已经具有它们的线程安全(thread-safe)版本,那么什么样的情形下,你才可以从能并发地枚举同一个被其它线程同时编辑的集合中获得好处?我们虽然对此已经有所了解,不过还是很想多听听大家的意见。
  2. 假设你确实具有第一条提到的情形,那么为了让从枚举器中返回的数据是可用的,你大概需要的最小保证措施是什么?例如,对于一个字典对象如果不存在并发编辑(添加 / 更新 / 删除),你可以认为它是线程安全的,你将能在枚举过程中准确地得到字典中的内容;然而,如果存在并发访问,你再也不能得到已经不存在于字典中的内容,你可能看不到并发添加或更新的东西,也可能依然能看到那些被并发地删除的条目。
  3. 如果我们确实支持在线程安全的集合上进行面向并发编辑的枚举操作,那么你希望能够从“在并发编辑上抛出异常”这样的行为中恢复之前的操作吗?
  4. 最后,你期望看到的既线程安全又能实现可伸缩副本的集合中,哪个最重要?

Omer van Kloeten 对于序列化,提出了一个重要的问题,

一个重要的附加功能是能够异步地转储(dump),即有时为了备份可以把内存的数据缓存到持久性存储,这就要求线程安全的枚举过程。(实际上,想一想——是否也能线程安全地序列化?这样的话什么才是默认的行为呢?)

Rick Brewster 则建议我们求助于函数式编程概念。代替在外部锁定集合的方式,所有对集合的并发操作都能通过给“Lock(Action)”方法传递一个委托来执行。

这个点子就是让“Lock”方法自动地用 lock/unlock 这样的结构把你的回调包围起来。这种方法也不会限制你使用这些类当前已经暴露出来的原子操作。实际上,也许让 Lock 来获得 Func 而非 Action 更好,并且 ConcurrentList 类本身不真正具有任何用于 get、set、enumerate 的方法。使用这种方式,你就只能访问在锁定范围内的类。

查看英文原文: Enumerating Concurrent Collections

2008-09-03 20:04736
用户头像

发布了 254 篇内容, 共 53.5 次阅读, 收获喜欢 2 次。

关注

评论

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

Prometheus Exporter (三十一)ProxySQL Exporter

耳东@Erdong

Prometheus 28天写作 exporter 12月日更 ProxySQL

Cordova应用的JavaScript代码和自定义插件代码的调试

Jerry Wang

JavaScript android 28天写作 12月日更 cordova

MQTT X v1.7.0 正式发布:MQTT 5.0 支持最为完整的客户端工具

EMQ映云科技

物联网 IoT mqtt

微信朋友圈高性能架构分析与设计

皓月

架构实战 #架构实战营 「架构实战营」

微信朋友圈高性能分析

swallowluo

架构训练营 架构实战营 「架构实战营」

关于HDFS中的Lease Recovery

Joseph295

架构实战营 第 4 期 模块二作业

架构实战营 模块二 「架构实战营」

实用机器学习笔记十八:过、欠拟合

打工人!

机器学习 深度学习 算法 学习笔记 12月日更

React进阶(九):React-Redux

No Silver Bullet

React React-Redux 12月日更

LabVIEW图像特征与机器视觉概念(理论篇—4)

不脱发的程序猿

机器视觉 图像处理 工业自动化 图像特征

Guava的布隆过滤器

程序员历小冰

算法 布隆过滤器 28天写作 12月日更

🏆【Alibaba中间件技术系列】「EasyExcel实战案例」实战研究一下EasyExcel如何从指定文件位置进行读取数据

洛神灬殇

EasyExcel Apache POI Alibaba 12月日更

Android ShareSDK 微博分享 (8995)app auth fail for appKey&sign&package 解决

阿策小和尚

28天写作 Android 小菜鸟 12月日更

Python爬虫反爬,你应该从这篇博客开启,UA反爬,Cookie 特定参数反爬

梦想橡皮擦

12月日更

dart系列之:这里不需要标新立异,dart代码最佳实践

程序那些事

flutter dart 代码规范 程序那些事 12月日更

Kubernetes + Spring Cloud 集成链路追踪 SkyWalking

zuozewei

链路追踪 性能测试 性能监控 12月日更

信贷风控从Model-centric到Data-centric

一直学习一直爽

互联网金融 风控模型 机器学习算法

跟着动画学Go数据结构之希尔排序

宇宙之一粟

golang 希尔排序 12月日更

模块二:朋友圈

撿破爛ぃ

「架构实战营」

架构训练营 - 模块二作业

伊静西蒙

JavaScript 数组方法 .map() 的 5 个使用场景

devpoint

JavaScript map array 12月日更

架构实战营模块2课后作业

墨宝

天下武功,无坚不摧,唯快不破

Tiger

28天写作

给弟弟的信第17封|拒绝自我感觉良好

大菠萝

28天写作

如何做一个区块链浏览器

Rayjun

区块链 区块链浏览器

王者荣耀商城异地多活架构设计

奔奔

前端开发:关于Vue组件中的data属性值是函数而不是对象的详解

三掌柜

28t 28天写作 12月日更

2021学习总结

将军-技术演讲力教练

模块七作业——王者荣耀商城异地多活架构设计

deng

架构实战营

从对象内存布局了解锁的膨胀

Ayue、

锁升级

在不丢失数据的情况下处理屏幕旋转 - Android

坚果

android 28天写作 12月日更

枚举并发集合探讨_.NET_Jonathan Allen_InfoQ精选文章