I am trying, and failing, to implement a Producer Consumer pattern in java, subject to the following constraints:
- The Producer produces into (and the Consumer consumes from) a queue with finite size
- There is a user interface with buttons toggling the Producer and Consumer, separately
- The Producer should produce only when queue is not full and the producer button is toggled active,
- The Consumer should consume only when the queue is not empty and the consumer button is toggled active.
- Both production and consumption should be possible at the same time. (It so happens that production will be at least as possible as consumption, and sometimes faster.)
My thought was to implement the buffer as a LinkedBlockingQueue of finite size, to handle the conditions relating to the queue empty/full states-- it should block when trying to put to a full queue or take from an empty one. Then, use a boolean state on the producer and the consumer, triggered off the buttons. Finally use a while/wait/loop in the producer and consumer, and a notify in the code for the buttons.
Something like the following, for the producer side:
while (true) {
if (!producing) { wait(); }
// generate a bunch of data and and finally
// Save this chunk of data
buffer.addData(data);
}
And in the code for the producer button, we both toggle the producing state and call a method on the producer that self notifies.
Problem: Once the producer is producing, it polls so hard even the UI (implemented in Swing) loses responsiveness. I can fix that by wadding a wait(1);
statement, but for various non-negotiable reasons that's just not acceptable. Some delay is inevitable, but a 1 ms delay each time through the loop just won't work.
I'm also not convinced I have the right understanding of the LinkedBlockingQueue, either, since if I let the the queue fill up, I still lose UI responsiveness. I am clearly misunderstanding how theaded operations in Java work, as I've tried multiple approaches and this is the closest I've got; previous approaches trying to handle the full/empty conditions "manually" without the LinkedBlockingQueue were miserable failures.
Any advice would be appreciated. Surely what I'm trying to do (lock on two conditions without excessive polling) isn't impossible, is it?