.NET 中的线程安全阻塞队列
在多线程同时访问队列进行读写操作的场景中,控制队列大小对于防止队列无限增长至关重要。本文讨论在 .NET 中创建自定义阻塞队列实现的方法。
一个简单的方案是使用集合作为队列的基础,并使用 AutoResetEvent
(_FullEvent) 在队列达到指定最大大小 (MaxSize) 时阻塞添加线程。移除项目时,发出 _FullEvent 信号以允许入队。
然而,由于同步不足,这种实现的安全性令人担忧。改进的方法是利用标准化的队列类型,并使用同步基元显式管理阻塞。
以下代码展示了改进后的实现:
<code class="language-csharp">class SizeQueue<T> { private readonly Queue<T> queue = new Queue<T>(); private readonly int maxSize; public SizeQueue(int maxSize) { this.maxSize = maxSize; } public void Enqueue(T item) { lock (queue) { while (queue.Count >= maxSize) { Monitor.Wait(queue); } queue.Enqueue(item); if (queue.Count == 1) { // 唤醒任何被阻塞的出队操作 Monitor.PulseAll(queue); } } } public T Dequeue() { lock (queue) { while (queue.Count == 0) { Monitor.Wait(queue); } T item = queue.Dequeue(); if (queue.Count == maxSize - 1) { // 唤醒任何被阻塞的入队操作 Monitor.PulseAll(queue); } return item; } } }</code>
此实现通过使用内置同步结构提供了一种安全高效的限制队列大小的机制。此外,它还包括优雅地关闭队列的功能,允许读取器干净地退出。
<code class="language-csharp">bool closing; public void Close() { lock(queue) { closing = true; Monitor.PulseAll(queue); } } public bool TryDequeue(out T value) { lock (queue) { while (queue.Count == 0) { if (closing) { value = default(T); return false; } Monitor.Wait(queue); } value = queue.Dequeue(); if (queue.Count == maxSize - 1) { // 唤醒任何被阻塞的入队操作 Monitor.PulseAll(queue); } return true; } }</code>
以上是如何在.NET中实现具有尺寸限制的线程安全阻塞队列?的详细内容。更多信息请关注PHP中文网其他相关文章!