如果我从Albahari的生产者/消费者队列实现中删除lock()会发生什么?

本文关键字:lock 删除 什么 实现 Albahari 生产者 队列 消费者 如果 | 更新日期: 2023-09-27 18:05:27

我正在学习多线程,遇到了一个生产者/消费者的问题。

下面是取自Albahari网站("c# in a Nutshell"系列丛书的作者)的生产者/消费者队列的示例实现:

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
    }
  }
}

我理解代码,但我的问题是,如果我删除"1"answers"2"注释行中的锁会发生什么?我试着想象不同的并发场景,但找不到一个会导致问题的场景。

如果你决定回答我的问题,请展示一个详细的一步一步的操作顺序,这会导致一个问题

如果我从Albahari的生产者/消费者队列实现中删除lock()会发生什么?

Queue<T>不是线程安全的。

如果你从多个线程写入,它将会中断。
(可能是当两个线程试图同时调整缓冲区大小时)

而且,即使它是线程安全的,删除第二个锁也会允许第二个线程在第一个线程在if内时删除最后一项,使第一个线程尝试读取空队列。