我有一个对象列表,许多线程中的许多对象都可以访问这些对象。为了确保线程安全,我将列表及其对象设置为只读。我唯一关心的是 List<>
对象的迭代器,因为我记得读过一些有关迭代器线程安全问题的内容。我有问题吗?
澄清一下:在 BarObservable 类中, List 栏>
栏是只读的。列表中的各个栏也是只读的。 MarketDataAdaptor 类使用 BarService 将新柱添加到 BarsObservable 类中。该图没有显示这一点,但 IBarObservers 被传递了对 List List 栏>
。他们无法写入它,但他们确实使用列表的迭代器。同时,最终的栏会更新,一旦完成,新的栏就会添加到列表的末尾。
I have a list of objects which will be accessible by many objects across many threads. To ensure thread safety I have made the list and its object read-only. My only concern is the iterators of the List<>
object because I remember reading something about iterator thread safety issues. Do I have a problem?
For clarification: in the BarObservable class, the List < Bar >
bar is read-only. The individual bars of the list are also read-only. The MarketDataAdaptor class uses BarService to add new bars to BarsObservable class. The diagram doesn't show this but the IBarObservers are passed a reference to the List < Bar >
. They can't write to it but they do use the iterator of the List. Meanwhile the final bar is updated and once finalized a new bar is added to the end of the list.
发布评论
评论(1)
据我了解,您当前提供了两个不变性保证:
List
对象的不变引用。这些都不足以处理任何并发读取器/写入器场景,因为
List
类型本身不是线程安全的。现在,您可以尝试使用锁、ReaderWriterLockSlims 等同步对列表的访问。您的具体操作方式将特定取决于您特定情况的生产者/消费者关系。例如,您可以通过以下任一方式在枚举期间锁定突变:
但我建议,如果您使用 .NET 4.0,请查看
System.Collections.Concurrent
命名空间。特别是,您可能会发现BlockingCollection
类正是您所需要的。
最后我会看一下整体设计,看看能不能用无锁的方式解决这个问题。
As I understand it, you currently provide two immutability guarantees:
List<Bar>
object.Bar
type itself is immutable or is, by convention, instances of it are not mutated after they are added to the list.Neither of these is sufficient to deal with any concurrent reader / writer scenarios since the
List<T>
type itself is not thread-safe.Now you could try synchronizing access to the list with locks, ReaderWriterLockSlims, etc. How you do this will be specific to the Producer / Consumer relationships of your particular situation. For example, you could lock mutation during enumeration by either of these:
But I would suggest, if you are on .NET 4.0, to take a look at the thread-safe collection classes in the
System.Collections.Concurrent
namespace. In particular, you may find theBlockingCollection<T>
class to be exactly what you need.Finally, I would look at the overall design to see if you can solve this problem in a lock-free manner.