我正在阅读一本名为“Beginning Algorithms”的书,其中包含 Java 示例。在关于队列的章节中,它解释了“阻塞队列”,并且......即使我的背景是 C# 而不是 Java,我觉得有些东西很有趣。
这是代码的一部分(我省略了不相关的部分):
public void enqueue(Object value){
synchronized(_mutex){
while(size == _max_size){
waitForNotification();
}
_queue.enqueue(value);
_mutex.notifyAll();
}
}
private void waitForNotification(){
try {
_mutex.wait();
} catch( InterruptedException e){
// Ignore
}
}
public Object dequeue() throws EmptyQueueException {
synchronized(_mutex){
while(isEmpty()){
waitForNotification();
}
Object value = _queue.dequeue();
_mutex.notifyAll();
return value;
}
}
我看到两个主要问题。
首先,如果队列已满,有 5 个线程正在等待添加项目,其他线程将 1 个项目出列,其他 5 个将被释放,同时检查“size() == _max_size”是否不再为真,并且他们将尝试调用“_queue.enqueue” 5 次,使队列溢出。
其次,同样的情况也发生在“出队”上。如果由于队列为空而阻止多个线程尝试使项目出队,添加一个将导致所有线程检查队列不再为空,并且所有线程都将尝试出队,得到 null 或我猜的异常。
我对吗?IC# 有一个“Monitor.Pulse”,它只释放一个被阻塞的线程,这会是解决方案吗?
干杯。