BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

构建更好的线程安全集合

| 作者 Jonathan Allen 关注 595 他的粉丝 ,译者 赵劼 关注 5 他的粉丝 发布于 2009年2月27日. 估计阅读时间: 3 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

大部分线程安全的集合都有一些基础性的缺陷:虽然每个操作都是线程安全的,但是多个操作无法组合起来使用。这意味着一些基本的执行顺序,例如在弹出顶部元素之前检查栈内元素数量会出现潜在的危险。尽管已经有一些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 queue) {
using (var locked = queue.Lock()) {
if (locked.Count > 0) {
var first = locked.Dequeue();
}
}
}

名为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
 

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

API Trick by Jeffrey Zhao

怎么说呢,我觉得这只是一个API Trick,其本质和SyncRoot没有太大区别,只是利用了语法的特性“确保”了——或者说“限制”了使用方式。
当然这也是有价值的,尤其是文章谈到利用了FxCop做静态检查,这是SyncRoot无法享受到的。

噱头 by 张 逸

这篇新闻属于典型的标题党。准确地说,这仅仅是提出一种集合编程中关于线程安全的编码规范而已。

如文中所说,这种做法仍然存在隐患。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

2 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT