Я пытаюсь и не могу реализовать шаблон Producer Consumer в java с учетом следующих ограничений:
- Производитель создает (а Потребитель потребляет) очередь конечного размера.
- Существует пользовательский интерфейс с кнопками, переключающими производителя и потребителя по отдельности.
- Производитель должен производить только тогда, когда очередь не заполнена и кнопка производителя активна,
- Потребитель должен потреблять только тогда, когда очередь не пуста и кнопка потребителя активна.
- И производство, и потребление должны быть возможны одновременно. (Так получается, что производство будет минимум максимально возможным по сравнению с потреблением, а иногда и быстрее.)
Моя идея состояла в том, чтобы реализовать буфер как LinkedBlockingQueue конечного размера, чтобы обрабатывать условия, относящиеся к состояниям пустой/полной очереди - он должен блокироваться при попытке поставить в полную очередь или взять из пустой. Затем используйте логическое состояние для производителя и потребителя, запускаемое кнопками. Наконец, используйте цикл while/wait/loop в производителях и потребителях и уведомление в коде для кнопок.
Что-то вроде следующего для стороны производителя:
while (true) {
if (!producing) { wait(); }
// generate a bunch of data and and finally
// Save this chunk of data
buffer.addData(data);
}
И в коде для кнопки производителя мы одновременно переключаем состояние производства и вызываем метод производителя, который самоуведомляется.
Проблема: как только производитель начинает производство, он так усердно опрашивает, что даже пользовательский интерфейс (реализованный в Swing) теряет отзывчивость. Я могу исправить это, добавив оператор wait(1);
, но по разным причинам, не подлежащим обсуждению, это просто неприемлемо. Некоторая задержка неизбежна, но задержка в 1 мс каждый раз при прохождении цикла просто не сработает.
Я также не уверен, что правильно понимаю LinkedBlockingQueue, поскольку, если я позволю очереди заполниться, я все равно потеряю отзывчивость пользовательского интерфейса. Я явно неправильно понимаю, как работают надстроенные операции в Java, поскольку я пробовал несколько подходов, и это самое близкое, что у меня есть; предыдущие подходы, пытавшиеся обрабатывать условия полного/пустого состояния «вручную» без LinkedBlockingQueue, потерпели неудачу.
Любой совет будет принят во внимание. Конечно, то, что я пытаюсь сделать (зафиксировать два условия без чрезмерного опроса), не невозможно, не так ли?