Я пытаюсь (и не могу) внедрить шаблон Потребитель-производитель в Java с учетом следующих ограничений:
- Производитель создает (а Потребитель потребляет из) очередь с конечным размером
- Имеется пользовательский интерфейс с кнопками, переключающими производителя и потребителя, отдельно
- Производитель должен выдавать только когда очередь не заполнена и кнопка производителя активна,
- Потребитель должен потреблять, только когда очередь не пуста и кнопка потребителя включена.
- Как производство, так и потребление должны быть возможны одновременно. (Бывает так, что производство будет , по крайней мере , насколько возможно, как потребление, а иногда и быстрее.)
Я думал о том, чтобы реализовать буфер как LinkedBlockingQueue конечного размера, чтобы обрабатывать условия, относящиеся к пустым / полным состояниям очереди - он должен блокироваться при попытке поставить в полную очередь или взять из пустой. Затем используйте логическое состояние для производителя и потребителя, которые срабатывают с кнопок. Наконец, используйте цикл while / wait / в производителе и потребителе и уведомление в коде для кнопок.
Что-то вроде следующего для стороны производителя:
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, были жалкими сбоями.
Любой совет будет оценен. Конечно, то, что я пытаюсь сделать (блокировка двух условий без чрезмерного опроса) не невозможно, не так ли?