硬核干货——《中小企业 AI 实战指南》免费下载! 了解详情
写点什么

构建更好的线程安全集合

  • 2009-02-26
  • 本文字数:1027 字

    阅读完需:约 3 分钟

大部分线程安全的集合都有一些基础性的缺陷:虽然每个操作都是线程安全的,但是多个操作无法组合起来使用。这意味着一些基本的执行顺序,例如在弹出顶部元素之前检查栈内元素数量会出现潜在的危险。尽管已经有一些 API 设法将某些操作绑定起来(例如.NET 4 的Coordination Data Structures ),但是它们往往会引入丑陋的方法(如TryDequeue)。

.NET 1 里的集合尝试了另一种方式,它们会对外暴露一个SyncRoot 属性,而不是在内部进行锁定。虽然SyncRoot 仍然是同步对象的默认机制,但是.NET 2 已经抛弃了SyncRoot/Wrapper 设计模式

那么该如何创建一个可用的组合式API 呢?Jared Parson 认为集合不应该直接暴露出线程安全的API,所有的方法都应该属于一个临时的对象,而这个对象只有在您锁定集合的时候才被创建出来。这个临时对象是集合的“钥匙”,只有钥匙的持有者才能获取集合内容。

以下示例为 Jared Parsons 的线程安全队列

复制代码
static void Example1(ThreadSafeQueue<int></int> queue) {<br></br> using (var locked = queue.Lock()) {<br></br> if (locked.Count > 0) {<br></br> var first = locked.Dequeue();<br></br> }<br></br> }<br></br>}

名为 locked 的对象本身不是线程安全的,但是开发人员只有在 using 代码块中才能正确执行操作。在遵守了这一简单规则之后,开发块里的所有代码就是线程安全的。Jared 解释道:

与大部分线程安全的设计一样,这些代码还是有被误用的可能:

  1. 在 ILockedQueue 销毁之后却继续使用它。这种做法应该被禁止,用户现有的知识一般足以避免这个问题。此外一些静态检查工具,例如 FxCop,会把这种做法识别为一个错误。我们也可以使用一种更严厉的做法来阻止此类情况出现:添加一个 disposed 标记,并在每个方法中进行检查。
  2. 如果用户在跨越多个 Lock 语句的情况下保留某个值(例如 Count),那么可能会对集合的状况出现错误的判断和假设。
  3. 如果用户没有正确销毁 ILockedQueue,那么这个对象会被永久锁定。幸运的是,对于实现了 IDisposable 的对象,FxCop 同样会将这种做法识别为一个错误——尽管这不是一个万分稳妥的机制。
  4. 无法确定用户是否会长期持有 ILockedQueue 对象。虽然 IDisposable 一般包含着“短期”的意味,但是这并不能做出完美的保证。
  5. ILockedQueue 并不是线程安全的。虽然一般情况下用户不会把 IDisposable 对象交给多个线程使用,但这也是必须考虑到的情况之一。

查看英文原文: Building a Better Thread-safe Collection

2009-02-26 06:281910
用户头像

发布了 157 篇内容, 共 61.2 次阅读, 收获喜欢 6 次。

关注

评论

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

架构师训练营第六周课后总结

Cloud.

手写一个Vue风格组件

林浩

Java 大前端 webpack

区块链技术助力打造新公益样板

CECBC

那些好用的命令

北漂码农有话说

性能压测的时候,系统响应时间和吞吐量如何变化,为什么?

不在调上

看动画学算法之:排序-归并排序

程序那些事

Java 算法 排序 归并排序

redis系列之——数据持久化(RDB和AOF)

诸葛小猿

redis 持久化 aof rdb

架构师训练营架构第七周总结

Cloud.

云原生技术栈的关键技术

李英俊

云原生 Go 语言

week7

不在调上

命令行一键启动Hadoop集群

我是个bug

大数据 hadoop hdfs YARN Big Data

【总结】性能优化

小胖子

kubernetes 集群安装(kubeadm)

小小文

Docker Kubernetes 群集安装 etcd

看动画学算法之:排序-选择排序

程序那些事

数据结构 算法 动画

生活困境

落曦

ARTS Week8

时之虫

ARTS 打卡计划

学习Rust,我的一些体会

Kurtis Moxley

编程 rust 随笔杂谈

区块链想要拥有互联网级的用户体验,如何从应用层与公链去改进?

CECBC

CECBC区块链专委会副主任吴桐受邀成为伏羲智库兼职研究员

CECBC

区块链技术 吴桐 商务部CECBC 伏羲智库 政务链

使用 Docker 部署 Django + MySQL 8 开发环境

AlwaysBeta

MySQL django Docker Dockerfile Docker-compose

流量控制算法

架构 流量控制 流控算法

LeetCode 题解:1051. 高度检查器,JavaScript,先排序再比较,详细注释

Lee Chen

大前端 LeetCode

Windows Sandbox

Dare Devor

Sandbox Virtualization

盘点本周区块链国内大事件

CECBC

隐私计算:实现数据价值释放的突破口

CECBC

密码学 政策扶持 隐私计算 发展现状

个人博客网站搭建

北漂码农有话说

Swift十年

SwiftMic

Swift十年

番外篇:新鲜上市的Unicorn - Pinterest的数据系统

顾仲贤

解决火狐新窗口打开网页被拦截问题

Lee Chen

大前端

可读代码编写炸鸡八 - 变量兜兜转转像是一场梦

多选参数

代码 代码组织 代码规范 可读代码编写 可读代码

第七章作业

小胖子

构建更好的线程安全集合_.NET_Jonathan Allen_InfoQ精选文章