
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Producer-Consumer Solution Using BlockingQueue in Java
Producer Consumer is the most common problem of Java concurrency and multi-threading. It arises during the synchronization that helps to manage multiple threads trying to access a shared resource. This article will help us to find Producer Consumer Solution using BlockingQueue in Java Thread.
Producer Consumer Problem and BlockingQueue
Understanding Producer Consumer Problem
Producer and Consumer are two distinct entities or processes that use a shared queue. This queue is of a fixed size buffer. The producer generates pieces of information and stores them in the queue. The consumer consumes the given information and removes them from the queue.
The actual problem occurs
When the producer keeps generating data even though the buffer is full.
When the consumer tries to remove data even the buffer is empty.
Either the producer or consumer's speed is slow.
Both are trying to update the buffer at the same time.
The solution
When the buffer is full, the producer must stop the data generation.
When the buffer is empty, the consumer must stop removing the information from the buffer.
Producer and Consumer work only when neither the buffer is empty nor it is full.
BlockingQueue
Java provides the BlockingQueue interface in ?java.util.concurrent' package. The main advantage of using this queue is that while retrieving and deleting an item, it waits for the queue to become non-empty. Also, while adding an item, it waits for available space. This feature makes it the perfect choice for the Producer Consumer Solution.
Syntax
BlockingQueue< Type > nameOfObject = new LinkedBlockingQueue<>();
Here, LinkedBlockingQueue is a class that implements BlockingQueue interface.
Producer Consumer Solution using BlockingQueue in Java
Approach
Create two classes and their corresponding constructors. Both classes will extend the ?Thread' class. The first class is for Producer and the Second one for Consumer.
In both classes, define BlockingQueue of type ?Integer' and pass them as a parameter to constructors. Here, ?Integer' is a wrapper class.
In Producer class, we override the in-built method ?run()' to produce the data from Producer end. Now, take for loop that will iterate 5 times and by using the ?put()' method, it will store data into BlockingQueue with an interval of 1 second.
In Consumer class, again override the in-built method ?run()' to consume the data from Consumer end using built-in method named ?take()'.
In the main() method, define an object of BlockingQueue and pass them to the constructor of both producer and consumer class as arguments
Example
import java.util.concurrent.*; class Producr extends Thread { protected BlockingQueue<Integer> blcque; Producr(BlockingQueue<Integer> blcque) { // constructor this.blcque = blcque; } public void run() { // overriding run method while (true) { for(int i = 1; i <= 5; i++) { try { System.out.println("Producer is running " + i); blcque.put(i); // to produce data // produce data with an interval of 1 sec Thread.sleep(1000); } // to handle exception catch (InterruptedException exp) { System.out.println("An interruption occurred at Producer"); } } } } } class Consumr extends Thread { protected BlockingQueue<Integer> blcque; Consumr(BlockingQueue<Integer> blcque) { // constructor this.blcque = blcque; } public void run() { // overriding run method try { while (true) { Integer elem = blcque.take(); // to consume data System.out.println("Consumer is running " + elem); } } // to handle exception catch (InterruptedException exp) { System.out.println("An interruption occurred at Producer"); } } } public class Solution { public static void main(String[] args) throws InterruptedException { // create an object of BlockingQueue BlockingQueue<Integer> bufrShr = new LinkedBlockingQueue<>(); // passing object of BlockingQueue as arguments Producr threadProd = new Producr(bufrShr); Consumr threadCon = new Consumr(bufrShr); // to start the process threadProd.start(); threadCon.start(); // to exit the process after 5 sec Thread.sleep(5000); System.exit(0); } }
Output
Producer is running 1 Consumer is running 1 Producer is running 2 Consumer is running 2 Producer is running 3 Consumer is running 3 Producer is running 4 Consumer is running 4 Producer is running 5 Consumer is running 5
Conclusion
We started this article by defining the Producer Consumer Problem and in the next section, we proposed a possible solution for this problem by introducing the BlockingQueue interface. In the end, we discussed a Java program that showed us how we can use BlockingQueue to solve the given problem practically.