Earlier we used Collections, they were never thread safe. Generics introduced in .NET 2.0 are
TypeSafe but not
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
But Generics are not
ThreadSafe, it’s a programmer’s responsibility. Means let’s say if you have a list collecting some objects. That list is shared amongst several threads, then it may work hazardously 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 data structure
ConcurrentStack<T>:Thread safe LIFO data structure
ConcurrentBag<T>: Thread safe implementation of an unordered collection
BlockingCollection<T>: Provides a Classical Producer Consumer pattern
All the above classes are available in the namespace
These collections allow us to share the data amongst several threads 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
- 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 retrieves it
TryRemove: Allows to do the specified operation like
Remove and if it fails, then does the alternative action.
Benefits of the above Concurrent collections:
- Now programmer doesn’t need to take care of thread safety.
- Uses light weight synchronization like
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
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. We’ll discuss other things in subsequent posts.