简体   繁体   English

Java中的阻塞队列

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM