Skip to main content

BlockingQueue for producer and consumer problem

How BlockingQueue fit into Solution

Any effective solution of producer consumer problem has to control the invocation of produce’s put() method which generates the resource – and consumer’s take() method which consumes the resource. Once you achieve this control of blocking the methods, you have solved the problem.
Java provides out of the box support to control such method invocations where one thread is creating resources and other is consuming them- through BlockingQueue. The Java BlockingQueue interface in the java.util.concurrent package represents a queue which is thread safe to put into, and take instances from.
blocking-queue
BlockingQueue is a construct where one thread putting resources into it, and another thread taking from it.
This is exactly what is needed to solve the producer consumer problem. Let’s solve the problem now !!

Using BlockingQueue to solve Producer Consumer problem

Producer

Below code is for producer thread.
class Producer implements Runnable
{
    protected BlockingQueue<Object> queue;
 
    Producer(BlockingQueue<Object> theQueue) {
        this.queue = theQueue;
    }
 
    public void run()
    {
        try
        {
            while (true)
            {
                Object justProduced = getResource();
                queue.put(justProduced);
                System.out.println("Produced resource - Queue size now = "  + queue.size());
            }
        }
        catch (InterruptedException ex)
        {
            System.out.println("Producer INTERRUPTED");
        }
    }
 
    Object getResource()
    {
        try
        {
            Thread.sleep(100); // simulate time passing during read
        }
        catch (InterruptedException ex)
        {
            System.out.println("Producer Read INTERRUPTED");
        }
        return new Object();
    }
}
Here, producer thread creates a resource (i.e. Object) and put it in queue. If queue is already full (max size is 20); then it will wait – until consumer thread pulls a resource out of it. So the queue size never goes beyond maximum i.e. 20.

Consumer

Below code is for consumer thread.
class Consumer implements Runnable
{
    protected BlockingQueue<Object> queue;
 
    Consumer(BlockingQueue<Object> theQueue) {
        this.queue = theQueue;
    }
 
    public void run() {
        try
        {
            while (true)
            {
                Object obj = queue.take();
                System.out.println("Consumed resource - Queue size now = "  + queue.size());
                take(obj);
            }
        }
        catch (InterruptedException ex)
        {
            System.out.println("CONSUMER INTERRUPTED");
        }
    }
 
    void take(Object obj)
    {
        try
        {
            Thread.sleep(100); // simulate time passing
        }
        catch (InterruptedException ex)
        {
            System.out.println("Consumer Read INTERRUPTED");
        }
        System.out.println("Consuming object " + obj);
    }
}
Consumer thread pulls a resource from queue if it’s there otherwise it will wait and then check again when producer has put something into it.

Testing Producer Consumer Solution

Now let’s test out producer and consumer components written above.
public class ProducerConsumerExample
{
    public static void main(String[] args) throws InterruptedException
    {
        int numProducers = 4;
        int numConsumers = 3;
         
        BlockingQueue<Object> myQueue = new LinkedBlockingQueue<>(20);
         
        for (int i = 0; i < numProducers; i++){
            new Thread(new Producer(myQueue)).start();
        }
             
        for (int i = 0; i < numConsumers; i++){
            new Thread(new Consumer(myQueue)).start();
        }
 
        // Let the simulation run for, say, 10 seconds
        Thread.sleep(10 1000);
 
        // End of simulation - shut down gracefully
        System.exit(0);
    }
}
When you run the code, you find output similar to below:
Consumed resource - Queue size now = 1
Produced resource - Queue size now = 1
Consumed resource - Queue size now = 1
Consumed resource - Queue size now = 1
Produced resource - Queue size now = 1
Produced resource - Queue size now = 1
Produced resource - Queue size now = 1
Consuming object java.lang.Object@14c7f728
Consumed resource - Queue size now = 0
Consuming object java.lang.Object@2b71e323
Consumed resource - Queue size now = 0
Produced resource - Queue size now = 0
Produced resource - Queue size now = 1
Produced resource - Queue size now = 2
Consuming object java.lang.Object@206dc00b
Consumed resource - Queue size now = 1
Produced resource - Queue size now = 2
Produced resource - Queue size now = 3
Consuming object java.lang.Object@1a000bc0
Consumed resource - Queue size now = 2
Consuming object java.lang.Object@25b6183d
Consumed resource - Queue size now = 1
Produced resource - Queue size now = 2
Produced resource - Queue size now = 3
...
...
Produced resource - Queue size now = 20
Consuming object java.lang.Object@2b3cd3a6
Consumed resource - Queue size now = 19
Produced resource - Queue size now = 20
Consuming object java.lang.Object@3876982d
Consumed resource - Queue size now = 19
Produced resource - Queue size now = 20
Output clearly shows that queue size never grows beyond 20, and consumer threads are processing the queue resources put by producer threads. It’s this much simple.

Comments

Popular posts from this blog

Yahoo! Calendar "Add Event" Seed URL Parameters

I can't seem to find any official documentation on this, so here are my notes. Some information gathered from  http://richmarr.wordpress.com/tag/calendar/ Other information gathered through trial and error, and close examination of the "Add Event" form on Yahoo!'s site. Yahoo! Calendar URL Parameters Parameter Required Example Value Notes v Required 60 Must be  60 . Possibly a version number? TITLE Required Event title Line feeds will appear in the confirmation screen, but will not be saved. May not contain HTML. ST Required 20090514T180000Z Event start time in UTC. Will be converted to the user's time zone. 20090514T180000 Event start time in user's local time 20090514 Event start time for an all day event. DUR value is ignored if this form is used. DUR 0200 Duration of the event. Format is HHMM, zero-padded. MM may range up to 99, and is converted into hours appropriately. HH values over 24 hours appear to be modulated by 24. Durations t...

HTML5 30-Day Course Outline

  🗓️ Week 1: HTML5 Fundamentals and Structure 🎯 Goal: Understand the structure of HTML5 and core elements. Day 1: Introduction to HTML5 ✅ Concepts What is HTML5 and its role in web development <!DOCTYPE html> declaration Basic HTML structure ( <html> , <head> , <body> ) Character encoding ( UTF-8 ) ✅ Example Code html <!DOCTYPE html > < html lang = "en" > < head > < meta charset = "UTF-8" > < title >My First HTML5 Page </ title > </ head > < body > < h1 >Hello World! </ h1 > </ body > </ html > ✅ Task: 👉 Create a basic HTML page with a title and h1 element. Day 2: HTML Elements and Semantics ✅ Concepts Block vs Inline Elements <div> , <span> , <article> , <section> , <aside> , <main> , <footer> Importance of semantic HTML for SEO ✅ Example Code html < article > < header > ...

Java KeyWords

Java Keywords Some identifiers are reserved in Java which has separate functionality and meaning such type of reserved identifiers are called reserved words. Java has 54 reserved keywords. We can divide them into the following categories. Primitive types and void : 9 keywords boolean : creates a boolean variable. The only possible values are true and false and the default value is false. byte : creates a byte variable. A byte takes 8-bits and ranges from -128 to 127. char : used to create a character variable. It takes 2-bytes and it’s unsigned. The value ranges from 0 to 65,536. short : create a short variable of 2-bytes. The value ranges from -32,768 to 32,767. int : create an integer variable, takes 4-bytes and the range is from -2,147,483,648 to 2,147,483,647 long : creates a long variable, takes 8-bytes and the range is from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. float : creates a signed floating point variable using 4-bytes. double ...