.NET 4.0 introduced the System.Collections.Concurrent namespace:
"The System.Collections.Concurrent namespace provides several thread-safe collection classes that should be used in place of the corresponding types in the System.Collections and System.Collections.Generic namespaces whenever multiple threads are accessing the collection concurrently"
BlockingCollection<T>
classConcurrentBag<T>
classConcurrentQueue<T>
classConcurrentDictionary<TKey, TValue>
classOrderablePartitioner<TSource>
classPartitioner
classIProducerConsumerCollection<T>
interfaceThe SynchronizedCollection<T>
class (available since .NET 3.0):
"Provides a thread-safe collection that contains objects of a type specified by the generic parameter as elements"
...is in the System.Collections.Generic
namespace.
So, why is the SynchronizedCollection<T>
class thread-safe but not concurrent?
What specifically makes the SynchronizedCollection<T>
generic class different and incompatible with collections from those in System.Collections.Concurrent
?
Update:
Let me rephrase the question:
What is the common denominator and distinguishing new feature in all generic collections that belong to the System.Collections.Concurrent
namespace, which is absent in (and impossible while using) the SynchronizedCollection<T>
generic class?
I changed the title to "What .NET 4.0 System.Collections.Concurrent
collection added in functionality to .NET 3.0 SynchronizedCollection
?".
But mostly I am interested to know what it is that made it impossible to do on the basis of .NET 3.0
Update2: Concerning the note:
"This question may already have an answer here:
What is the difference between SynchronizedCollection and the other concurrent collections?"
The answer is confusing in context of my question - are the new features evolutionary (using pre-.NET 4.0 features) or revolutionary (unavailable in pre-.NET 4.0)?
Concurrent namespace. This has several collection classes that are thread-safe and scalable. These collections are called concurrent collections because they can be accessed by multiple threads at a time.
ConcurrentDictionary<TKey,T> Concurrent dictionary is thread-safe collection.
The main reason for this slowness is locking; synchronized collections lock the whole collection e.g. whole Map or List while concurrent collection never locks the whole Map or List. They achieve thread safety by using advanced and sophisticated techniques like lock stripping.
The concurrent collection APIs of Java provide a range of classes that are specifically designed to deal with concurrent operations. These classes are alternatives to the Java Collection Framework and provide similar functionality except with the additional support of concurrency.
The previous thread-safe collection classes have a rather major flaw, they cannot be iterated in a thread-safe way. Iterating is in general very difficult to make thread-safe, there is no clean way to make code that uses an iterator aware of items that are added to or removed from a collection while the code is iterating the collection. The only truly safe way is to lock access to the collection while the iteration is taking place. That's very undesirable, such a lock will typically be held for a very long time. Next best way is to make a copy of the collection, a copy that won't be modified so can always be safely iterated. Nobody likes the O(n) storage requirement of that solution.
The Synchronized() method in the .NET 1.0 collection classes was particularly troublesome. Microsoft did not make it a secret that iterating isn't thread-safe. They even added code to detect the mishap, it throws an exception when a thread modified the collection. This exception however doesn't occur often enough and bewildered .NET programmers that failed to read the warning label and just flat-out assume that surely a thread-safe collection is safe no matter what you do. Well, it wasn't and calling a collection "thread-safe" when the most basic operation on a collection isn't thread-safe is of course a problem. What Microsoft meant was "it is thread-safe because using threads won't corrupt the collection". What programmers read was "it is thread-safe". Microsoft didn't repeat the same mistake in the .NET 2.0 generic collection classes.
This was addressed in .NET 4, iterating the new collections won't throw an exception. They will not otherwise do anything to prevent your code from misbehaving because it is reading stale data. That's an unsolvable problem that you have to solve yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With