.NET 4.0 并发集合
.NET 4.0 并发集合
以前我们使用的集合类都不是线程安全的。 .NET 2.0 中引入的泛型是类型安全
,但不是线程安全
的。
泛型类型安全
意味着在声明任何泛型类型时,你需要指定 List 将要保存的类型。并且当你从 List 中检索任何项目时,你将获得实际类型项目,而不是像从 ArrayList
中获得的那样的 Object
。
但是泛型不是线程安全
的,这取决于程序员的责任。 也就是说,如果你有一个 List 收集了一些对象,并且该 List 在多个线程之间共享,那么如果两个线程尝试在同一时间访问该 List
,例如同时添加/删除/迭代 List 中的项目,则可能会出现问题。
可以通过锁定集合和其他类似方式来实现线程安全。 但是,为了添加/删除一个项目而锁定整个 List,对于基于特定情况的应用程序来说,可能会带来巨大的性能损失。
.NET 4.0 提供了新的并发类,即并发集合。 这些是
ConcurrentDictionary< Key , Value>
:线程安全的键值对字典ConcurrentQueue<T>
:线程安全的 FIFO 数据结构ConcurrentStack<T>
:线程安全的 LIFO 数据结构ConcurrentBag<T>
:线程安全的无序集合实现BlockingCollection<T>
:提供经典的生产者-消费者模式
以上所有类都可以在 System.Collections.Concurrent
命名空间中找到。
这些集合允许我们在不担心任何问题的情况下,在多个线程之间共享数据。
并发集合是 .NET 4.0 中引入的并行编程的关键。
那么我们来讨论最常用的 List ConcurrentDictionary
。
- 字典中线程安全的添加/删除操作。
- 非常友好的方法,使得在添加/删除之前无需检查键是否存在。
AddOrUpdate
:如果不存在则添加新条目,否则更新现有条目GetOrAdd
:如果存在则检索项目,否则先添加它然后检索它TryAdd
、TryGetValue
、TryUpdate
、TryRemove
:允许执行指定的Add
/Get
/Update
/Remove
操作,如果操作失败,则执行替代操作。
以上并发集合的优点
- 现在程序员无需关心线程安全问题。
- 使用轻量级同步,如
SpinWait
、SpinLock
等,这些同步机制在将线程置于等待状态之前会进行自旋 - 对于短时间等待,自旋比涉及内核转换的等待更高效。 - 意味着在多线程环境下更快的添加/删除/迭代,而无需编写相关代码。
- 像
ConcurrentQueue
和ConcurrentStack
这样的其他类不依赖于锁,而是依赖于 Interlocked 操作,这使得它们更快。
关于这一点还有很多可以讨论的。 但保持简洁明了,我们先到此结束。 我们将在后续文章中讨论其他内容。
