2012-03-21 5 views
1

Я пытаюсь, и неспособность, чтобы реализовать Производитель потребительских шаблон в Java, с учетом следующих ограничений:Производитель Потребитель в Java с UI Переключить

  • Продюсер производит в (и потребитель потребляет от) очередь с конечным размером
  • Там есть пользовательский интерфейс с кнопками переключая производитель и потребитель, отдельно
  • производитель должен производить только тогда, когда очередь не полная и кнопку производителя переключены активны,
  • Потребитель должен потреблять только тогда, когда очередь не пуста и кнопка потребителя активирована.
  • Оба продукта и потребление должны быть возможны одновременно. (Это так случается, что производство будет по крайней мере, насколько это возможно, как потребление, а иногда и быстрее.)

Моя мысль была реализовать буфер как LinkedBlockingQueue конечного размера, для обработки условий, связанных с очередью empty/full states - он должен блокироваться при попытке поставить в полную очередь или взять из пустого. Затем используйте логическое состояние производителя и потребителя, вызванное кнопками. Наконец, используйте 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, были неудачными сбоями.

Любые советы будут оценены. Конечно, то, что я пытаюсь сделать (заблокировать два условия без чрезмерного опроса), не исключено, не так ли?

ответ

4

Это discussion включает в себя программу TwoTimer, в котором Приращивает javax.swing.Timer в int при 100 Гц, тогда как java.util.TimerTask образцов значение при 1 Гц. Вариант хранит образцы в LinkedBlockingQueue, образуя недавнюю очередь истории. Это напрямую не связано с вашей задачей, но это иллюстрирует существенное требование для гибкого графического интерфейса: никогда не блокируйте поток отправки событий. В примере используется invokeLater() для выполнения следующей коллекции.

Также рассмотрите nextGaussian() для имитации латентности, как показано на рисунке here.

В качестве альтернативы вам может понравиться example, который оживляет очередь геометрических фигур.

2

То, что вы описали, должно работать нормально. Проведение вашего фактического кода (абстрактное фактическое производство и фактическое потребление) поможет. Вы сказали, что

опрашивает так трудно даже пользовательский интерфейс теряет отзывчивость

, что, кажется, означает, что вы злоупотребляя LinkedBlockingQueue. Вы не должны повторять опрос очереди. Вы должны получить элемент из очереди, обработать его, затем проверить флаг производства, а также создать и поставить в очередь элемент или ждать() на мониторе, на который пользовательский интерфейс вызывает notifyAll().

+0

Но производство и потребление ** могут быть включены одновременно, но они не являются ** обязательными **. Таким образом, производство может быть включено без потребления. Завтра добавлю дополнительный код. – Novak

Смежные вопросы