Производитель / Потребитель, использующий ожидание и уведомление

Я пытаюсь согласовать проблему с продюсером и потребителем. Производитель ставит в очередь 10 объектов. То есть метод запуска продюсера включает в себя простой цикл для добавления 10 объектов, после чего он завершается. Когда очередь заполнена (размер очереди 10), в методе добавления очереди вызывается wait() - >. На стороне потребителя потребитель начинает с того, что смотрит на объекты, а затем начинает их удалять. Проблема, с которой я столкнулся, заключается в том, что примерно в 50% случаев, когда программа запускается, вывод завершается после того, как производитель помещает 10 объектов в очередь. Остальные 50% случаев программа работает нормально, то есть потребитель снимает все объекты. Моим предыдущим решением этой проблемы было создание нового потребительского потока в методе запуска производителя. Поэтому, как только производитель поместил десять объектов в очередь, был создан новый потребительский поток, и я использовал 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;


}

1 ответ

Производитель никогда не уведомляет потребительскую ветку. Поэтому, если потребитель запускается первым, он находит очередь пустой и ждет вечно.

Я бы просто использовал BlockingQueue, который сделает это за вас.

Если вы действительно хотите использовать wait() а также notify()Вам необходимо:

  • использовать петлю вокруг вашего wait() звонки и возврат в состояние ожидания, если условие для пробуждения не соответствует действительности
  • решить, когда производитель должен уведомить (обычно, когда он помещает элемент в очередь)
  • decide when the consumer should notify (normally, when it removes an item from the queue)
  • decide when the consumer should wait (normally, when the queue is empty)
  • decide when the producer should wait (normally, when the queue is full)
  • stop ignoring InterruptedException. Just let them propagate.

я хотел бы использовать notifyAll(), which would also make sure that everything works well if there are several producers or consumers.

Другие вопросы по тегам