并发集合
1 为什么使用并发集合?
原因主要有以下几点:
- System.Collections和System.Collections.Generic名称空间中所提供的经典列表、集合和数组都不是线程安全的,若无同步机制,他们不适合于接受并发的指令来添加和删除元素。
- 在并发代码中使用上述经典集合需要复杂的同步管理,使用起来很不方便。
- 使用复杂的同步机制会大大降低性能。
- NET Framework 4所提供的新的集合尽可能地减少需要使用锁的次数。这些新的集合通过使用比较并交换(compare-and-swap,CAS)指令和内存屏障,避免使用互斥的重量级锁。这对性能有保障。
注意:
与经典集合相比,并发集合会有更大的开销,因此在串行代码中使用并发集合无意义,只会增加额外的开销且运行速度比访问经典集合慢。
2 并发集合
1)ConcurrentQueue:线程安全的先进先出 (FIFO) 集合
主要方法:
- Enqueue(T item);将对象添加到集合结尾。
- TryDequeue(out T result); 尝试移除并返回位于集合开始处的对象,返回值表示操作是否成功。
- TryPeek(out T result);尝试返回集合开始处的对象,但不将其移除,返回值表示操作是否成功。
说明:
- ConcurrentQueue是完全无锁的,但当CAS操作失败且面临资源争用时,它可能会自旋并且重试操作。
- ConcurrentQueue是FIFO集合,某些和出入顺序无关的场合,尽量不要用ConcurrentQueue。
2)ConcurrentStack:线程安全的后进先出 (LIFO) 集合
主要方法及属性:
- Push(T item);将对象插入集合的顶部。
- TryPop(out T result);尝试弹出并返回集合顶部的对象,返回值表示操作是否成功。
- TryPeek(out T result);尝试返回集合开始处的对象,但不将其移除,返回值表示操作是否成功。
- IsEmpty { get; }指示集合是否为空。
- PushRange(T[] items);将多个对象插入集合的顶部。
- TryPopRange(T[] items);弹出顶部多个元素,返回结果为弹出元素个数。
说明:
- 与 ConcurrentQueue相似地,ConcurrentStack完全无锁的,但当CAS操作失败且面临资源争用时,它可能会自旋并且重试操作。
- 获取集合是否包含元素使用 IsEmpt

本文介绍了NET Framework 4中的并发集合,如ConcurrentQueue、ConcurrentStack、ConcurrentBag、BlockingCollection和ConcurrentDictionary,强调了它们在多线程编程中的重要性和性能优势。并讨论了并发集合的常用模式,如生产者-消费者和流水线模式,以及如何利用这些集合实现高效并发操作。
最低0.47元/天 解锁文章
2678

被折叠的 条评论
为什么被折叠?



