C# 如果我从Albahari的生产者/消费者队列实现中删除lock(),会发生什么
我正在学习多线程,遇到了生产者/消费者的问题 以下是《简而言之》系列丛书的作者:C# 如果我从Albahari的生产者/消费者队列实现中删除lock(),会发生什么,c#,.net,multithreading,C#,.net,Multithreading,我正在学习多线程,遇到了生产者/消费者的问题 以下是《简而言之》系列丛书的作者: 使用系统; 使用系统线程; 使用System.Collections.Generic; 类ProducerConsumerQueue:IDisposable { EventWaitHandle_wh=新的自动存储事件(false); 螺纹工; 只读对象_locker=新对象(); 队列_tasks=新队列(); 公共产品消费者队列() { _工人=新线程(工作); _worker.Start(); } 公共void
使用系统;
使用系统线程;
使用System.Collections.Generic;
类ProducerConsumerQueue:IDisposable
{
EventWaitHandle_wh=新的自动存储事件(false);
螺纹工;
只读对象_locker=新对象();
队列_tasks=新队列();
公共产品消费者队列()
{
_工人=新线程(工作);
_worker.Start();
}
公共void排队任务(字符串任务)
{
锁(_locker)/队列
不是线程安全的
如果您从多个线程写入,它将中断。
(可能是两个线程同时尝试调整缓冲区大小时)
此外,即使是线程安全的,移除第二个锁也会允许第二个线程移除最后一项,而第一个线程位于if
中,使第一个线程尝试读取一个空队列。在他的最后一句话中,SLaks指的是工作()方法。但是在单个对象实例上只能有一个线程执行该方法。那么,为什么我们需要第二个锁呢?@Junior1993:因为这些方法不是线程安全的,所以队列仍然可以中断。SLaks,请您详细解释一下(一步一步)如果我们只移除第二个锁,它怎么会断开?@Junior1993:一个线程调用Enqueue()
,而另一个线程调用Dequeue()
。在第一个线程将队列大小调整为新数组后,第二个线程修改了旧数组。我只是好奇我的问题有什么不对,有人否决了它?”
using System;
using System.Threading;
using System.Collections.Generic;
class ProducerConsumerQueue : IDisposable
{
EventWaitHandle _wh = new AutoResetEvent (false);
Thread _worker;
readonly object _locker = new object();
Queue<string> _tasks = new Queue<string>();
public ProducerConsumerQueue()
{
_worker = new Thread (Work);
_worker.Start();
}
public void EnqueueTask (string task)
{
lock (_locker) // <---------------------------------------------- 1
_tasks.Enqueue (task);
_wh.Set();
}
public void Dispose()
{
EnqueueTask (null); // Signal the consumer to exit.
_worker.Join(); // Wait for the consumer's thread to finish.
_wh.Close(); // Release any OS resources.
}
void Work()
{
while (true)
{
string task = null;
lock (_locker) // <---------------------------------------------- 2
if (_tasks.Count > 0)
{
task = _tasks.Dequeue();
if (task == null) return;
}
if (task != null)
{
Console.WriteLine ("Performing task: " + task);
Thread.Sleep (1000); // simulate work...
}
else
_wh.WaitOne(); // No more tasks - wait for a signal
}
}
}