4

在下面的代码中,我在这个例子中使用两个线程来共享理智的资源,queue所以我需要使用locken-queueing or dequeuing如果是,那么为什么,因为程序似乎工作正常。

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);
            }
        }
    }
}
4

1 回答 1

8

是的,你这样做,System.Collections.Generic.Queue<T>对于同时写入和读取来说不是线程安全的。您需要在 enquing 或 dequing 之前锁定同一个对象,或者如果您使用的是 .NET 4/4.5,请改用System.Collections.Concurrent.ConcurrentQueue<T>该类并使用该TryDequeue方法。

到目前为止,您当前的实现没有给您带来问题的原因是由于Thread.Sleep(500)调用(不是您应该在生产代码中使用的东西),这意味着自读取操作以来从prodThread队列中读取时不会写入队列consumeThread耗时不到 500 毫秒。如果您消除Thread.Sleep可能性,它会在某个时候抛出异常。

于 2012-12-21T23:40:33.923 回答