繁体   English   中英

.NET中的线程安全集合

[英]Thread safe collections in .NET

当需要线程安全集合(例如Set)时,现在的标准是什么。 我自己同步它,还是有固有的线程安全集合?

.NET 4.0 Framework在System.Collections.Concurrent命名空间中引入了几个线程安全的集合:

ConcurrentBag <T>
表示线程安全,无序的对象集合。

ConcurrentDictionary <TKey,TValue>
表示可以由多个线程同时访问的键值对的线程安全集合。

ConcurrentQueue <T>
表示线程安全的先进先出(FIFO)集合。

ConcurrentStack <T>
表示线程安全的后进先出(LIFO)集合。


默认情况下,.NET Framework中的其他集合不是线程安全的,需要为每个操作锁定:

lock (mySet)
{
    mySet.Add("Hello World");
}

Pre .net 4.0 .Net中的大多数集合都不是线程安全的。 你必须自己做一些工作来处理同步: http//msdn.microsoft.com/en-us/library/573ths2x.aspx

文章引用:

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

使用Synchronized方法创建一个线程安全的包装器,并通过该包装器专门访问该集合。

如果类没有Synchronized方法,则从类派生并使用SyncRoot属性实现Synchronized方法。

访问集合时,在SyncRoot属性上使用锁定机制(如C#中的lock语句(Visual Basic中的SyncLock))。

同步根属性
锁定声明

Object thisLock = new Object();
......
lock (thisLock)
{
    // Critical code section
}

在.net 4.0中,引入了System.Collections.Concurrent命名空间

阻止收藏
并行袋
并发队列
并发字典
Ordable Partitioner
分区
分区T

.NET 4在System.Collections.Concurrent下提供了一组线程安全的集合

除了System.Collections.Concurrent非常有用的类之外​​,在大多数读取很少更改的场景中(或者如果有频繁但非并发写入)也适用于.Net的一种标准技术被称为写时复制

它具有一些高度并发程序所需的属性:

  • 集合对象实例本身是不可变的(即线程安全,可以安全地枚举而不锁定)
  • 修改可以占用所需的时间,读取的性能和并发性不受影响
  • 通常可以实现将任何非线程安全的数据结构转换为其中的数据结构

限制:如果存在并发写入,则可能必须重试修改,因此获得的并发写入越多,其效率就越低。 (那是乐观的并发工作)

编辑 Scott Chamberlain的评论提醒我,还有另一个限制:如果您的数据结构庞大,并且经常进行修改,那么在内存消耗和所涉及的复制CPU成本方面,写入时全部复制可能都是禁止的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM