并发集合可以安全地从不同的线程进行修改



假设我有:

MyCollection = new ConcurrentDictionary<string, int>();

我现在可以安全地从MyCollection中添加和删除项目。但是修改项目呢。例如,这样做安全吗:

MyCollection["key"] = 1;   // thread 1

MyCollection["key"] = 2;   // thread 2

示例2:

MyCollection2 = new ConcurrentDictionary<string, List<int>>();

这样做安全吗?

MyCollection2["key"].Add(1);  // Thread1

MyCollection2["key"].Add(2);  // Thread2

其中Thread1和Thread2同时执行。修改项目时是否必须创建锁?

修改项是否安全完全取决于它是否在ConcurrentDictionary中。这与你从两个不同的线程中变异出一个列表没有什么不同。在List的情况下,它是不安全的;如果使用设计为的类型从多个不同的线程进行突变,例如ConcurrentDictionary<string, ConcurrentQueue<int>>,那么这就可以了。

ConcurrentQueue确保对该类的方法的调用被观察为原子调用;它在螺纹安全方面没有做出任何其他保证。

第一个是完全安全的。ConcurrentDictionary是线程安全的,因此同时在不同线程上获取/设置值不会引起问题。

你的第二个不安全。仅仅因为ConcurrentDictionary包含对X类型实例的引用并不能使X类型成为线程安全的。在访问任何特定键的值时,它也不会阻塞。

记住,

MyCollection2["key"].Add(1);

与相同

var list = MyCollection2["key"];
list.Add(1);

很明显,在这种情况下,所有线程安全的代码(ConcurrentDictionary访问)都已完成,但非线程安全代码(List<T>访问)具有而不是

最新更新