Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to use locking in the following c# code?

In the following code I am using two threads to share sane resource in this example it's a queue so do I need to use lock while en-queueing or dequeuing if yes then why because program seems to work fine.

class Program
{   
    static Queue<string> sQ = new Queue<string>();

    static void Main(string[] args)
    {
        Thread prodThread = new Thread(ProduceData);
        Thread consumeThread = new Thread(ConsumeData);
        prodThread.Start();
        consumeThread.Start();
        Console.ReadLine();
    }

    private static void ProduceData()
    {
        for (int i = 0; i < 100; i++)
        {
            sQ.Enqueue(i.ToString());               
        }
    }

    private static void ConsumeData()
    {
        while (true)
        {
            if (sQ.Count > 0)
            {
                string s = sQ.Dequeue();
                Console.WriteLine("DEQUEUE::::" + s);
            }
        }
    }
}
like image 563
Embedd_0913 Avatar asked Feb 19 '23 02:02

Embedd_0913


1 Answers

Yes you do, System.Collections.Generic.Queue<T> is not thread safe for being written to and read from at the same time. You either need to lock on the same object before enquing or dequing or if you are using .NET 4/4.5 use the System.Collections.Concurrent.ConcurrentQueue<T> class instead and use the TryDequeue method.

The reason your current implementation has not caused you a problem so far, is due to the Thread.Sleep(500) call (not something you should be using in production code) which means that the prodThread doesn't write to the queue while the consumeThread reads from it since the read operation takes less than 500ms. If you remove the Thread.Sleep odds are it will throw an exception at some point.

like image 129
Trevor Pilley Avatar answered Feb 20 '23 14:02

Trevor Pilley