Earlier we used Collections, they were never ThreadSafe. Generics introduced in .NET 2.0 are TypeSafe but not ThreadSafe.
Generics are Typesafe means whenever you are going to declare any generic type, you need to specify the type that is going to be held by the List. And whenever you are going to retrieve any item from list you will get the actual type item, not an Object like we get from Arraylist.
But Generics are not ThredSafe, it’s a programmer’s responsibility. Means let’s say if you have an list collecting some objects. That list is shared amongst several threads, the it may work hazardous if two threads try to access the List at the same point of time, like adding/removing/iterating items from the same list at the same time.
Thread safety can be implemented with the help of locking the collection and other similar ways. But locking the entire list for the sake of adding/removing an item could be a big performance hit for an application based on the circumstances.
.NET 4.0 provides new classes for the concurrency as Concurrent collections. These are
- ConcurrentDictionary< Key , Value> Thread safe dictionary in key value pairs.
- ConcurrentQueue<T> Thread safe FIFO datastructure.
- ConcurrentStact<T> Thread safe LIFO datastructure.
- ConcurrentBag<T> Thread safe implementation of an unordered collection.
- BlockingCollection<T> Provides a Classical Producer Consumer pattern.
Above all classes are available in the namespace System.Collections.Concurrent .
These collections allow us to share the data amongst several thread without any worry.
Concurrent Collections are the key of Parallel programming, that is introduced in .NET 4.0
So let’s discuss the very commonly used list ConcurrentDictionary
- A thread safe add/remove from dictionary.
- Very user friendly methods that make it unnecessary for code to check if a key exists before add/remove.
- AddOrUpdate : Adds a new entry if doesn’t exist else updates existing one
- GetOrAdd : Retrieves an item if exists, else first adds it then retrieve it
- TryAdd, TrygetValue,TryUpdate, TryRemove : Allows to do the specified operation like Add/Get/Update/Remove and if it fails the does the alternative action.
Benefits of the above Concurrent collections:
- Now programmer doesn’t need to take care on threadsafety.
- Uses light weight synchronization like SpinWait, SpinLock etc that use spinning before putting threads to wait – for short wait periods, spinning is less expensive than wait which involves kernel transition.
- Means faster add/remove/iterate in multithreading environment without writing the code for it.
- Some other classes like ConcurrentQueue & ConcurrentStack don’t rely on Interlocked operations instead of locks which make them faster.
There is lot more to discuss on this. But keeping it short and simple, let’s finish it we’ll discuss other things coming subsequent posts.