Producer Consumer Design Pattern with Blocking Queue Example in Java
Producer/Consumer Relationship: ArrayBlockingQueue / Multithreading from Java(c) How to Program. In continuation of my previous blog, let's try to solve the Producer Consumer Problem using BlockingQueue. Ummm Before proceeding with. A pipeline is the composition of many producer/consumer relationships into a larger It's fairly simple to build a socalled blocking queue that provides this.
Producer/Consumer Relationship: ArrayBlockingQueue
Image here explains this problem in an effective way. If you refer to the problem statement above and look at the image, we see that there are so many entities who are ready with their part of data. However, there are not enough workers who can process all the data. Hence, as the producers continue to line-up in a queue it just continues to grow.
Producer/Consumer Relationship: ArrayBlockingQueue | Multithreading
We see that the systems start to hog up threads and take a lot of time. Intermediate Solution Producer Consumer: The Intermediate approch We do have an intermediate solution. Refer to the image and you will immediately notice that the producers are piling up their work in a filing cabinet and the worker continues to pick it up as they get done with the previous task.
However, this approach does have some glaring shortcomings: There is still one worker who has to do all the work.
The external systems may be happy, but the task will still continue to exist until the worker has completed all of the tasks The producers will pile up their data in a queue and it needs resources to hold the same. Just as in this example the cabinet can fill up, the same can happen with the JVM resources too.
We need to be careful how much data we are going to place in memory and in some cases it may not be much.
Java™ How To Program (Early Objects), Tenth Edition by Harvey Deitel, Paul Deitel
Class BlockingBufferTest Screenshot contains the main method that launches the app. Line 11 creates the ExecutorService, and line 14 creates a BlockingBuffer object and assigns its reference to Buffer variable sharedLocation. Lines execute the Producer and Consumer Runnables.
Line 26 calls method shutdown to end the app when the Producer and Consumer finish. In our prior synchronization examples, the output statements in the Buffer's set and get methods that indicated what the Producer was writing or the Consumer was reading were always executed while the Buffer's lock was held by the thread calling set or get.
- Concurrency Pattern: Producer and Consumer
This guaranteed the order in which the output would be displayed. If the Consumer had the lock, the Producer could not execute the set methodtherefore, it was not possible for the Producer to output out of turn. The reverse was also true. In Screenshotmethods set and get no longer use locksall locking is handled by the ArrayBlockingQueue.
This problem can be implemented or solved by different ways in Java, classical way is using wait and notify method to communicate between Producer and Consumer thread and blocking each of them on individual condition like full queue and empty queue.
With introduction of BlockingQueue Data Structure in Java 5 Its now much simpler because BlockingQueue provides this control implicitly by introducing blocking methods put and take. Now you don't require to use wait and notify to communicate between Producer and Consumer.
BlockingQueue put method will block if Queue is full in case of Bounded Queue and take will block if Queue is empty. In next section we will see a code example of Producer Consumer design pattern. Using Blocking Queue to implement Producer Consumer Pattern BlockingQueue amazingly simplifies implementation of Producer-Consumer design pattern by providing outofbox support of blocking on put and take.