joydip_kanjilal
Contributor

Working with thread safe collections: ConcurrentStack and ConcurrentQueue

opinion
Aug 26, 20164 mins
Software Development

The ConcurrentStack and ConcurrentQueue classes, lock-free and thread-safe implementations of the Stack and Queue classes, build thread safe collections in .Net

Thread safe collections were first introduced in .Net 4 with the introduction of the System.Collections.Concurrent namespace. The collection types in the System.Collections.Concurrent namespace contains a collection of thread safe collection classes.

ConcurrentStack

A stack is a data structure that works on LIFO (last in first out) basis. The ConcurrentStack class is a thread safe counterpart of the generic Stack class. The ConcurrentStack is a thread safe generic collection class that was first introduced as part of .Net Framework 4. Here’s the list of the important methods of this class that illustrate the possible operations.

  1. Push(T element) – this method is used to add data of type T.
  2. PushRange – this method can be used to add an array of items of type T.
  3. TryPop(out T) – this method is used to retrieve the first element from the stack. It returns true on success, false otherwise.
  4. TryPeek(out T) – this method is used to retrieve the next element from the stack but it doesn’t remove the element from the stack. Note that similar to the TryPop(out T) method, it returns true on success and false otherwise.
  5. TryPopRange – this method is overloaded and works similar to the TryPop but is used for retriving arrays from the stack

Here’s how you can create an instance of the ConcurrentStack class and push data to it.

ConcurrentStack<Int32> concurrentStack = new ConcurrentStack<Int32>();

for (Int32 index = 0; index < 10; index++)

{

       concurrentStack.Push(index);

}

To retrieve the elements from out of a concurrent stack, you can leverage the TryPop(out T) method as shown below.

Int32 data;

bool success = concurrentStack.TryPop(out data);

The following code listing illustrates how you can store and retrieve data to and from a concurrent stack.

static void Main(string[] args)

       {

           ConcurrentStack<Int32> concurrentStack = new ConcurrentStack<Int32>();

           for (Int32 index = 0; index < 100; index++)

           {

               concurrentStack.Push(index);

           }

           while (concurrentStack.Count > 0)

           {

               Int32 data;

               bool success = concurrentStack.TryPop(out data);

               if (success)

              {

                   Console.WriteLine(data);

               }

           }

           Console.Read();

       }

When you execute the above code listing, the numbers 0 to 99 will be displayed in the reverse order at the console window.

ConcurrentQueue

A queue is a data structure that works on the basis of FIFO (first in first out). The ConcurrentQueue class in .Net acts as a thread safe FIFO based generic queue.

The following is the list of the important methods in the ConcurrentQueue class.

  1. Enqueue(T element) – this method is used to add an item of type T to the queue
  2. TryPeek(out T) – this method is used to retrieve the next element from the queue but it doesn’t remove the element from the queue. This method returns true on success and false when it fails.
  3. TryDequeue(out T) – this method is used to retrieve the first element from the queue. Contrary to the TryPeek(out T) method, it removes the element from the queue. This method returns true on success and false otherwise.

The following code snippet shows how you can create an instance of the ConcurrentQueue class to store integers.

ConcurrentQueue<Int32> concurrentQueue = new ConcurrentQueue<Int32>();

To store elements to the concurrent queue instance you can take advantage of the Enqueue method as shown below.

concurrentQueue.Enqueue(100);

The following code listing illustrates how you can store and retrieve elements to and from a concurrent queue.

ConcurrentQueue<Int32> concurrentQueue = new ConcurrentQueue<Int32>();

for (int index = 0; index < 100; index++)

{

     concurrentQueue.Enqueue(index);

}

Int32 item;

while (concurrentQueue.TryDequeue(out item))

{

     Console.WriteLine(item);

}

When you execute the above code listing, the numbers 0 to 99 will be displayed at the console window.

Note that both ConcurrentStack and ConcurrentQueue classes are thread safe and they can manage locking and synchronization issues internally.

You can also convert the concurrent queue instance to an array by making a call to the ToArray() method. The following code snippet illustrates how this can be achieved.

ConcurrentQueue<Int32> concurrentQueue = new ConcurrentQueue<Int32>();

for (Int32 index = 0; index < 100; index++ )

   concurrentQueue.Enqueue(index);

Int32[] integerArray = concurrentQueue.ToArray();

foreach (int i in integerArray)

{

   Console.WriteLine(i);

}

The IsEmpty property of the ConcurrentQueue class returns true is the collection is empty, false otherwise. The following code snippet shows how you can use this method.

ConcurrentQueue<Int32> concurrentQueue = new ConcurrentQueue<Int32>();

for (Int32 index = 0; index < 100; index++ )

concurrentQueue.Enqueue(index);

while(!concurrentQueue.IsEmpty)

{

     Int32 result;

     concurrentQueue.TryDequeue(out result);

     Console.WriteLine(result);

}

joydip_kanjilal
Contributor

Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net.

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference, which is held twice each year.

More from this author