2

Let's say I have ConcurrentDictionary<int, HashSet<int>> sampleCollection;. Is it thread safe to perform operations on sampleCollection[1] (which is a HashSet<int>)?

In general, if we have a not thread-safe collection inside a thread-safe collection, is it thread-safe to operate the not thread-safe collection through the thread-safe outer one?

VMh
  • 1,300
  • 1
  • 13
  • 19
  • 1
    Generally, no, since the HashSet could be referenced and accessed from outside the dictionary. – shay__ Oct 07 '15 at 14:44
  • What if it only is accessed through the dictionary? – VMh Oct 09 '15 at 02:34
  • Think about it - what would happen if thread1 gets a hashset from the dictionary to iterate it, and thread2 gets the same hashset to add an item to it, **at the same time thread1 is iterating it**? – shay__ Oct 11 '15 at 07:21

3 Answers3

3

The HashSet does not know that it is aggregated in a safe data structure. it has no way to find out. It can't adjust it's behavior.

Even if HashSet was special cased to somehow cooperate and be safe in this constellation you could never assume that for an arbitrary type.

Data structures and algorithms have to be designed specially to be thread safe. Anything not documented to be safe is assumed unsafe.

usr
  • 168,620
  • 35
  • 240
  • 369
  • I forgot to point out that all threads will access the HashSet through sampleCollection[index] and not through a direct reference (eg stored in a variable: like myhashset = sampleCollection[1]), so modifications to the HashSet are coming from a reference to the HashSet provided by a ConcurrentDictionary which is thread-safe. So, in my scenario, a modification to the hashset is in the context of a modification to the ConcurrentDictionary. – VMh Oct 08 '15 at 15:55
  • 1
    @VMh the hashset can't know through which reference it was called. This can't possibly make a difference. – usr Oct 09 '15 at 17:55
0

If the HashSet can be modified after the first time it entered the ConcurrentDictionary, then it isn't thread safe. The right answer is No.

shay__
  • 3,815
  • 17
  • 34
0

From the other answers here you already understand that HashSet<int> in the ConcurrentDictionary<int, HashSet<int>> sampleCollection; is not thread-safe because (as justly put by @usr), it has not way to find out that it is aggregated in a thread-safe data structure.

You can instead use ConcurrentDictionary<int, ConcurrentBag<int>> sampleCollection; to realize your purpose.

displayName
  • 13,888
  • 8
  • 60
  • 75