代码之家  ›  专栏  ›  技术社区  ›  Andrew

为什么C中没有并发集合?

  •  15
  • Andrew  · 技术社区  · 15 年前

    我正在尝试了解C中集合背后的线程安全理论。

    为什么Java中没有并发的集合呢?( java docs )。有些集合似乎是线程安全的,但我不清楚其位置,例如关于:

    • 复合作战,
    • 使用迭代器的安全性,
    • 写入操作

    我不想重新发明轮子!(我不是多线程专家,绝对不会低估这有多困难)。

    我希望社区能提供帮助。

    3 回复  |  直到 15 年前
        1
  •  28
  •   Jon Skeet    15 年前

    到目前为止,.NET还具有相对“低级别”的并发支持,但是.NET 4.0引入了 System.Collections.Concurrent 包含各种安全且有用的集合的命名空间。

    安德鲁的答案在如何处理.NET 4.0之前的托收方面是完全正确的-当然还有 在访问“普通”共享集合时使用I'd just lock appropriately。然而,并发集合使生产者/消费者队列等的使用变得容易。

        2
  •  19
  •   Andrew Hare    15 年前

    C提供了跨多个线程处理集合的几种方法。对于这些技巧的一个好的描述,我建议您从 Collections and Synchronization (Thread Safety) 以下内容:

    默认情况下,集合类为 一般不线程安全。倍数 读者可以用 信心;但是,任何修改 到集合生成未定义的 访问的所有线程的结果 收藏,包括读者 线程。

    集合类可以成为线程 安全使用下列任何一种 方法:

    • 使用synchronized方法创建线程安全包装,以及 以独占方式访问集合 通过包装袋。
    • 如果类没有同步方法,则从 类并实现同步 方法使用SyncRoot属性。
    • 使用锁定机制,例如c(synclock-in)中的lock语句 Visual Basic),在SyncRoot上 访问时的属性 收集。
        3
  •  6
  •   saret    15 年前

    正如jon skeet提到的,现在在.NET 4的system.collections.concurrent命名空间中有“线程安全”集合。

    在以前的.NET框架版本中不存在并发集合(至少我猜是这样)的原因之一是,即使使用并发集合,也很难保证线程安全。

    (这并非完全正确,因为有些集合提供了一个同步方法,从非线程安全集合返回线程安全集合,因此存在一些线程安全集合…)

    例如,假设一个有一个线程安全字典——如果只想插入,如果该键不存在,则首先查询集合以查看该键是否存在,如果该键不存在,则执行插入。不过,这两个操作不是线程安全的,在containsKey的查询和add操作之间,另一个线程可能已经插入了该键,因此存在争用条件。

    换句话说,集合的操作是线程安全的——但使用它并不一定是安全的。在这种情况下,需要转换回传统的锁定技术(mutex/monitor/semaphore…)以实现线程安全性,因此并发收集在多线程安全性方面没有给您带来任何好处(但可能对性能不利)。

    推荐文章