[英]Blocking queue in Java
I am reading a book titled "Beginning Algorithms", that has examples in Java. 我正在阅读一本书,标题为“ Beginning Algorithms”,其中包含Java实例。 In the chapter about queues, it explains the "blocking queue", and ... even when my background is C# and not Java, something looks funny to me.
在关于队列的章节中,它解释了“阻塞队列”,并且...即使我的背景是C#而不是Java,在我看来也很有趣。
This is part of the code ( I have omitted non relevant parts ): 这是代码的一部分(我省略了不相关的部分):
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;
}
}
I see two major problems. 我看到两个主要问题。
First, if the queue is full, 5 threads are waiting to add items, and other thread dequeue 1 item, the other 5 will be released, will check at the same time that "size() == _max_size" is not true anymore and they will try to call "_queue.enqueue" 5 times, overflowing the queue. 首先,如果队列已满,有5个线程正在等待添加项目,而其他线程使1个项目出队,则其他5个线程将被释放,同时检查“ size()== _max_size”不再为真,并且他们将尝试调用“ _queue.enqueue” 5次,从而导致队列溢出。
Second, similarly the same happens with "dequeue". 第二,“出队”同样发生。 If several threads are blocked trying to dequeue items because the queue is empty, adding one, will cause all of them to check that the queue is not empty anymore, and all of them will try to dequeue, getting null or an exception I guess.
如果由于队列为空而阻止了多个线程尝试出队,则添加一个线程将导致所有线程检查队列是否不再为空,并且所有线程都将尝试出队,得到null或我猜到的异常。
Am I right? 我对吗? IC# there is a "Monitor.Pulse" that only releases one blocked thread, would that be the solution?
IC#有一个“ Monitor.Pulse”,它仅释放一个阻塞的线程,那是解决方案吗?
Cheers. 干杯。
You are disregarding the synchronized
statement. 您正在忽略
synchronized
语句。 This allows only one thread to acquire the _mutex
. 这仅允许一个线程获取
_mutex
。 Consequently, only that one thread will be able to check the value of size
because the while
statement is within the synchronized
block. 因此,由于
while
语句在synchronized
块内,因此只有一个线程能够检查size
的值。
As described in this thread , the wait()
method actually releases the _mutex
object and waits for a call to notify()
, or notifyAll()
in this case. 如该线程中所述,
wait()
方法实际上释放_mutex
对象,并在这种情况下等待对notify()
或notifyAll()
的调用。 Furthermore, notifyAll()
will only grant the lock on _mutex
to one of the waiting threads. 此外,
notifyAll()
将只授予对锁_mutex
到等待线程之一 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.