Reputation: 36048
Let say I have:
MyCollection = new ConcurrentDictionary<string, int>();
I now it is safe to add and remove items from MyCollection
. But What about modifying items. For example is it safe to do:
MyCollection["key"] = 1; // thread 1
and
MyCollection["key"] = 2; // thread 2
MyCollection2 = new ConcurrentDictionary<string, List<int>>();
Is it safe to do?
MyCollection2["key"].Add(1); // Thread1
and
MyCollection2["key"].Add(2); // Thread2
where Thread1 and Thread2 are executing at the same time. Do I have to create a lock when modifying items?
Upvotes: 0
Views: 130
Reputation:
The first is perfectly safe. The ConcurrentDictionary is thread safe, so getting/setting values on different threads at the same time won't cause issues.
Your second is not safe. Just because a ConcurrentDictionary contains a reference to an instance of type X does not make type X thread safe. Neither does it block while accessing the value of any particular key.
Remember,
MyCollection2["key"].Add(1);
is the same as
var list = MyCollection2["key"];
list.Add(1);
It is clear that, in this case, all thread-safe code (ConcurrentDictionary access) has completed, but non-thread safe code (List<T>
access) has not.
Upvotes: 2
Reputation: 203802
Whether or not it is safe to modify the item is entirely independent on whether or not it is in a ConcurrentDictionary
. That's no different than just having a list that you mutate from two different threads. In the case of List
, it's not safe; if you use a type that is designed to be mutated from multiple different threads, such as a ConcurrentDictionary<string, ConcurrentQueue<int>>
then that would be fine.
ConcurrentQueue
is only ensuring that calls to methods of that class are observed to be atomic; it is making no other guarantees surrounding thread safety.
Upvotes: 5