Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / programming / threads

ThreadSafe Collections

4.75/5 (10 votes)
20 Oct 2014CPOL2 min read 14.2K  
Thread safe collections

Introduction

This tip is all about collections which are thread safe.

When we are programming into a multithreaded environment and need to have some collections into memory, then we can use collections to make them thread safe either by using locking and unlocking.

Other is using a thread safe collection.

First, let's have a look at locking unlocking situation.

Let's assume we are having a dictionary:

C#
Dictionary<int, int> data = new Dictionary<int, int>();
Parallel.For(0, 10000, delegate(int i)
           {
                   dicp.Add(i, i);
           });

And now, by using a parallel loop, we are going to add 0 to 10000 into the dictionary.

After running this code, what will happen is it will throw an error of out of range exception, because a collection keeps on increasing, but in parallel it will not be able to do so properly.

Other case, let’s say we are adding 0 to 1000 into this collection; it will let us add them successfully.

But if you write those values using a loop, then you find that they are not in the right order. So they will not be. :) Because we are using multithread environment.

But the funny thing is, sometimes you can find that the basic functionality of a Dictionary is broken. This is a key value pair. You might find two keys to be exactly the same. Because different threads tried to enter the same value into the dictionary and they successfully did so.

So, now we are into a mess!

Now how to resolve such an issue.

The answer lies within the title of this article with an additional option of using locks?

C#
Parallel.For(0, 10000, delegate(int i)
         {            
         lock (dicp)
             {
                 dicp.Add(i, i);
             } 
         });

Using the same logic and locking the resource, so that only one thread can access it at one time is one solution.

Now our issue is resolved.

But let’s say somewhere we forgot to add lock, then we are again in a mess.

So, we will not end up creating a mess, there is a prebuilt solution in .NET called thread safe collections.

We are having many of thread safe collections based on their features and can use them according to our need:

  • BlockingCollections <t>
  • ConcurrentBag <t>
  • ConcurrentDictionary < tkey,t >
  • ConcurrentQueue <t>
  • ConcurrentStack <t>

There are many more to explore:

C#
BlockingCollection<int> dl = new BlockingCollection<int>();
          Parallel.For(0, 10000, delegate(int i)
          {
              dl.Add(i);                            
          });

This piece of code will work just fine no issues at all.

Other is using a dictionary:

C#
ConcurrentDictionary<int, int> cc = new ConcurrentDictionary<int, int>();
 
Parallel.For(0, 10000, delegate(int i)
{
    cc.TryAdd(i, i); 
});

Works like a piece of cake ? ;)

Happy coding!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)