-2

我正在尝试协调生产者和消费者线程问题。生产者将 10 个对象放入队列中。那就是生产者的 run 方法只包括一个简单的循环来添加 10 个对象然后它就完成了。当队列已满(队列大小为 10)时,会在队列的 add 方法中调用 wait() ->。在消费者方面,消费者首先查看对象,然后开始删除它们。我遇到的问题是,在大约 50% 的情况下,当程序运行时,输出会在生产者将 10 个对象放入队列后终止。其他 50% 的时间程序运行良好 - 即消费者取下所有物品。我之前对这个问题的解决方案是在生产者的 run 方法中创建一个新的消费者线程。所以一旦生产者将十个对象放入队列中,创建了新的消费者线程,我使用 join() 来同步操作。但是我想让这个过程与等待和通知一起工作。有人可以告诉我我做错了什么吗?谢谢

    @Override
    public synchronized boolean add(Process element) {
    if(isFull())
    {
        waitForNotify();
    }

    else
    {          

       queue.add(element);



    }
    return true;
}

    private void invokeNotify() {
    try {
        notify();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

    private void waitForNotify() {
    try {
        wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

     @Override
     public synchronized boolean offer(Process element) throws IllegalStateException {
       queue.add(element);
       this.queue = newHeapSort.heapify(queue, queue.size());
       return true;



}

    @Override
    public synchronized Process peek() {
    if(queue.isEmpty())
    {
        waitForNotify();
    }
    return(queue.get(0));

}

    @Override
    public synchronized Process head() {    
    if(queue.isEmpty()) 
    {
        invokeNotify();
    }

        Process head = queue.get(0);
        queue.remove(0);


        return head;


}
4

1 回答 1

3

生产者从不通知消费者线程。所以如果消费者是第一个开始的,它会发现队列是空的,然后永远等待。

我会简单地使用一个 BlockingQueue,它会为你做到这一点。

如果你真的想使用wait()and notify(),你需要:

  • 在您的呼叫周围使用循环wait(),如果唤醒条件不成立,则返回等待状态
  • 决定生产者何时应该通知(通常是在将项目放入队列时)
  • 决定消费者何时应该通知(通常,当它从队列中删除一个项目时)
  • 决定消费者何时应该等待(通常,当队列为空时)
  • 决定生产者何时应该等待(通常,当队列已满时)
  • 停止忽略 InterruptedException。只是让他们传播。

我会使用notifyAll(),如果有多个生产者或消费者,这也将确保一切正常。

于 2012-11-23T17:35:36.130 回答