线程锁定/独占访问改进

时间:2011-03-30 20:17:47

标签: multithreading c#-4.0 locking thread-safety mutex

我有2个线程方法在2个不同的位置运行,但同时共享访问列表数组对象(让我们称之为 PriceArray ),第一个线程添加必要时从PriceArray 删除项目(数组内容从第三方数据提供者更新),平均更新速率介于0.5和1秒之间。

第二个线程只使用foreach循环每隔3秒读取一次数组的内容(占用大部分项目,但不是全部)。

为了确保在第二个线程循环遍历数组时避免讨厌的Collection was modified; enumeration operation may not execute异常,我在lock(PriceArray)的第一个线程中包装了添加和删除操作,以确保独占访问并防止发生该异常。问题是当第二种方法尝试循环遍历数组项时,我注意到了性能问题,因为大多数时候数组被添加/删除线程锁定。

让场景以这种方式运行,您是否有任何建议如何使用C#4.0中的其他线程安全/独占访问策略来提高性能?

感谢。

2 个答案:

答案 0 :(得分:1)

是的,还有很多选择。

最好/最简单的方法是切换到System.Collections.Concurrent中使用适当的集合。这些都是线程安全的集合,允许您在不管理自己的锁的情况下使用它们。它们通常无锁或使用非常精细的锁定,因此可能会显着改善您从同步中获得的性能影响。

另一个选择是使用ReaderWriterLockSlim让读者不要互相阻挡。由于第三方库正在编写此阵列,因此这可能是更合适的解决方案。它允许你在写作期间完全阻止,但读者在阅读期间不需要相互阻止。

答案 1 :(得分:1)

我的建议是ArrayList.Remove()占用大部分时间,因为为了执行删除,它会执行两件昂贵的事情:

  1. 线性搜索:只需逐个获取元素并与要删除的元素进行比较
  2. 当找到要删除的元素的索引时 - 它将其下方的所有内容向左移动一个位置。
  3. 因此,每次删除都需要花费一定的时间来计算当前集合中元素的数量。

    因此,您应该尝试使用更适合此任务的结构替换ArrayList。我需要有关您案例的更多信息,以建议选择哪一个。