开发者

Is Queue.Peek thread safe?

开发者 https://www.devze.com 2022-12-08 20:57 出处:网络
A read operat开发者_JAVA技巧ion on a 32 bit field is atomic. So if the queue holds object references the Queue.Peek method should be thread safe, right?No.And even if it were, that misses the point. L

A read operat开发者_JAVA技巧ion on a 32 bit field is atomic. So if the queue holds object references the Queue.Peek method should be thread safe, right?


No. And even if it were, that misses the point. Let's assume a thread-safe peek for a moment. You typically end up writing code that does something kind of like this:

if (MyQueue.Peek() != null)
  var item = MyQueue.Dequeue();

That's a bug in multi-threaded code even if Peek() and Dequeue() are themselves both thread-safe, because you need to remember that the queue can change in between when you check with Peek() and when you act on the information it gives you with Dequeue(). You need to make sure you lock around both parts.


No, you should still lock around each Peek() call.

Since Queue internally uses an Array, its instance methods are not thread safe, because array could be changed by a different thread at any time.

Peek() also checks for queue length to see if there are elements in the queue before returning the actual value, and some other thread might remove those elements before the method actually returns those values.


If you look at the implementation in .net reflector, it looks like this...

public virtual object Peek()
{
    if (this._size == 0)
    {
        throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyQueue"));
    }
    return this._array[this._head];
}

So no. Not thread safe.


It is not thread safe.

But to synchronize it you may find a ReaderWriterLockSlim to be the best. Only the Enqueue() and Dequeue() methods would require a write-lock. Peek() would only require a read-lock.

0

精彩评论

暂无评论...
验证码 换一张
取 消