看到新的System.Collections.Concurrent
名称空间出现,我很激动.Net 4.0,相当不错!我看过ConcurrentDictionary
、ConcurrentQueue
、ConcurrentStack
、ConcurrentBag
和BlockingCollection
.
有一件东西似乎神秘地丢失了,那就是ConcurrentList<T>
.我必须自己写(或从网上下载:)吗?
我是不是漏掉了什么明显的东西?
看到新的System.Collections.Concurrent
名称空间出现,我很激动.Net 4.0,相当不错!我看过ConcurrentDictionary
、ConcurrentQueue
、ConcurrentStack
、ConcurrentBag
和BlockingCollection
.
有一件东西似乎神秘地丢失了,那就是ConcurrentList<T>
.我必须自己写(或从网上下载:)吗?
我是不是漏掉了什么明显的东西?
I gave it a try a while back(也是on GitHub).我的实现遇到了一些问题,在这里我将不讨论这些问题.让我告诉你,更重要的是,我学到了什么.
首先,你不可能得到IList<T>
的完整实现,它是无锁和线程安全的.特别是,随机插入和删除是有效的,除非你也忘记了O(1)随机访问(也就是说,除非你"作弊",只是使用某种链表,让索引变得糟糕).
Ithought可能值得使用的是线程安全的、有限的IList<T>
子集:特别是,它允许Add
,并通过索引提供随机read-only访问(但没有Insert
、RemoveAt
等,也没有随机write访问).
这是my ConcurrentList<T>
implementation的目标.但是当我在多线程场景中测试它的性能时,我发现simply synchronizing adds to a 101 was faster.基本上,加到List<T>
已经很快了;涉及的计算步骤的复杂性微不足道(递增索引并分配给数组中的元素;即really it).您需要ton个并发写操作才能看到任何类型的锁争用;即使这样,每次写操作的平均性能仍将击败ConcurrentList<T>
中成本更高但无锁的实现.
在相对罕见的情况下,列表的内部数组需要自行调整大小,您需要支付少量成本.因此,我最终得出结论,这是一个one小众场景,在这个场景中,仅添加ConcurrentList<T>
个集合类型是有意义的:当您希望在every single call上添加一个元素的开销较低时(因此,与摊销性能目标相反).
它并不像你想象的那么有用.