繁体   English   中英

为什么在以下阻塞队列示例中调用notify()的顺序很重要?

[英]Why is the order in which notify() is called in the following blocking queue example important?

我针对Prod-Cons问题编写了一个简单的Blocking Queue示例。 下面的示例无效。 除非我在等待线程上用通知交换入队/出队逻辑的添加/删除部分。 我在BlockingQueue的任何实现中都找不到对此行为的明确解释。 在入队部分中,添加元素然后进行通知是否正确? 这样,我可以保证,当Consumer线程运行时,它应该有一个消费者元素,并且不会返回null。 请解释。

import java.util.LinkedList;
import java.util.Queue;

public class BlockingQueueCustom<T> {

    private int size = 10;
    private Queue<T> queue = new LinkedList<T>();

    public BlockingQueueCustom(int s) {
        this.size = s;
    }

    public synchronized void enqueue(T element) throws InterruptedException {
        while (queue.size() == size) {
            wait();
        }
        queue.add(element); //Comment this part to make it work
        if (queue.size() == 0) {
            this.notifyAll();
        }
        //queue.add(element); Uncommenting this will make it work
    }

    public synchronized T dequeue() throws InterruptedException {
        while (queue.size() == 0) {
            this.wait();
        }
        T element = queue.remove(); //Comment this part to make it work
        if (queue.size() == size) {
            this.notifyAll();
        }
            return element; //Comment this part to make it work
        //return queue.remove(); Uncommenting this will make it work
    }
} 

在入队部分中,添加元素然后进行通知是否正确?

这部分并不重要,因为您使用的是同步方法-除非您仍然退出enqueue方法,否则其他线程将无法运行。 但是,对于size()的测试确实很重要。 看这里:

if (queue.size() == 0)

如果刚刚添加了元素,您如何期望这是正确的? 您可以检查它是否为1,这意味着添加元素之前 ,它必须为0。或者可以保留一个单独的变量:

boolean shouldNotify = queue.size() == 0;
queue.add(element);
if (shouldNotify) {
    this.notifyAll();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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