Ful*_*oof 10 c# collections concurrency multithreading thread-safety
.NET 4.0引入了System.Collections.Concurrent命名空间:
" System.Collections.Concurrent命名空间提供了几个线程安全的集合类,只要多个线程同时访问集合,就应该使用它们代替System.Collections和 System.Collections.Generic命名空间中的相应类型"
BlockingCollection<T> 类ConcurrentBag<T> 类ConcurrentQueue<T> 类ConcurrentDictionary<TKey, TValue> 类OrderablePartitioner<TSource> 类Partitioner 类IProducerConsumerCollection<T> 接口该SynchronizedCollection<T>班(因为.NET 3.0中提供):
"提供一个线程安全的集合,其中包含泛型参数指定的类型的对象作为元素"
...在System.Collections.Generic命名空间中.
那么,为什么SynchronizedCollection<T>类是线程安全但不并发?
具体是什么使得SynchronizedCollection<T>泛型类与那些中的集合不同并且不兼容System.Collections.Concurrent?
更新:
让我重新解释一下这个问题:属于System.Collections.Concurrent命名空间的所有泛型集合中的共同点和区分新特性是什么,这在SynchronizedCollection<T>通用类中是不存在的(并且在使用时不可能)?
我将标题更改为" System.Collections.Concurrent在.NET 3.0中添加了什么.NET 4.0 集合SynchronizedCollection?".
但大多数情况下,我很想知道是什么让它无法在.NET 3.0的基础上进行
更新2:关于说明:
"这个问题可能已经有了答案:
答案在我的问题的背景下令人困惑 - 新功能是进化的(使用预4.0版功能)还是革命性的(在.NET 4.0之前不可用)?
以前的线程安全集合类有一个相当大的缺陷,它们不能以线程安全的方式进行迭代.迭代通常很难使线程安全,没有干净的方法来使代码使用迭代器知道在代码迭代集合时添加到集合或从集合中删除的项目.唯一真正安全的方法是在迭代发生时锁定对集合的访问.这是非常不受欢迎的,这种锁定通常会持续很长时间.接下来最好的方法是制作一个集合的副本,一个不会被修改的副本,因此总是可以安全地迭代.没有人喜欢该解决方案的O(n)存储要求.
.NET 1.0集合类中的Synchronized()方法特别麻烦.微软没有说明迭代不是线程安全的秘密.他们甚至添加了代码来检测事故,它在线程修改集合时抛出异常.然而,这种异常并不经常发生,并且令人困惑的.NET程序员无法读取警告标签而只是平坦地认为无论你做什么,肯定一个线程安全的集合是安全的.好吧,当集合上最基本的操作不是线程安全时,它不是并且调用集合"线程安全"当然是一个问题.微软的意思是"它是线程安全的,因为使用线程不会破坏集合".程序员读到的是"它是线程安全的".Microsoft在.NET 2.0泛型集合类中没有重复同样的错误.
这在.NET 4中得到了解决,迭代新集合不会引发异常.否则他们不会做任何事情来防止你的代码行为不端,因为它正在读取过时的数据.这是一个无法解决的问题,你必须自己解决.
.NET 4.0的主要焦点是并发性.Microsoft 在.NET 4.0中引入了System.Threading.Tasks命名空间,因此添加System.Collections.Concurrent命名空间也是有意义的.正如其他地方所提到的,System.Collections.Concurrent中的集合具有高性能,因为它们是以无锁方式实现的.这不是一件容易的事,我认为这就是微软认为它属于新的主要.NET版本而不是刷新.NET 3.x的原因.AFAIK无锁行为是使用Interlocked.CompareExchange的通用版本实现的,它也是.NET 4.0的新增功能.
如果您对如何实现System.Collections.Concurrent类感兴趣,我建议您阅读他在.NET 4.0发布之前编写的 Joe Duffy的书"Windows上的并发编程".该书展示了如何实现一些并发集合.
| 归档时间: |
|
| 查看次数: |
8239 次 |
| 最近记录: |