这个BlockingQueue线程安全吗

本文关键字:安全 线程 BlockingQueue 这个 | 更新日期: 2023-09-27 17:53:44

我正在尝试实现一个最小线程安全阻塞队列,我想到的是:

class BlockingQueue<T>
{
    private Queue<T> myQueue = new Queue<T>();
    private SemaphoreSlim semaPhore = new SemaphoreSlim(0); 
    public void Enqueue(T t)
    {
        lock(myQueue)
        {
            myQueue.Enqueue(t);
            semaPhore.Release();
        }
    }
    public T Dequeue()
    {       
        semaPhore.Wait();
        lock(myQueue)
        {
            return myQueue.Dequeue();
        }
    }
}

我试着对几个生产商和消费者进行压力测试,同时以随机时间间隔排队/出队,但没有失败。

然而,如果我仔细查看代码,"semaPhore.Wet(("answers"lock(myQueue("命令之间会发生什么事情吗?

这个BlockingQueue线程安全吗

是的,它可能发生。。。Thread.Abort()会破坏此队列。

semaPhore.Wait();
// Here a Thread.Abort() happens
lock(myQueue) ...

然后发生的情况是,队列中有一个元素没有人能够恢复,因为"空闲"信号量槽比队列项目少一个。

除此之外(还有专家在.NET4.0中编写的BlockingCollection<>(,我认为代码是正确的。semaPhore.Release()会导致一个隐式屏障(因为它在内部使用lock(,所以在内存中的写入顺序没有问题(首先Enqueue()会被真正地完成,然后Release()会被完成(。请注意,它将在执行中,因为每个操作都需要两个lock(您的加上SemaphoreSlim中的一个(。

根据我现在提出的建议,令人惊讶的是,它使用的代码行更少:(

class BlockingQueue<T>
{
    private Queue<T> myQueue = new Queue<T>();
    public void Enqueue(T t)
    {
        lock(myQueue)
        {
            myQueue.Enqueue(t);
            Monitor.Pulse(myQueue);
        }
    }
    public T Dequeue()
    {       
        lock(myQueue)
        {
            Monitor.Wait(myQueue);
            return myQueue.Dequeue();
        }
    }
}