Thursday, 12 April 2018

Producer-Consumer Java Program Using wait notify

This Java program solves the Producer-Consumer problem using threads and wait notify. Where one (Producer) thread produces data and another (consumer) thread retrieves it. This program makes use of inter-thread communication using wait, notify, notifyAll.

Producer-Consumer problem

Producer Consumer problem is one of the classic concurrency problem where two processes Producer and Consumer share a common buffer for inserting or retrieving data.

Task of the Producer is to generate data and insert it into the shared buffer.

Task of the Consumer is to consume data from the shared buffer.

Since both of these processes work in tandem and share a buffer so it becomes important to synchronize their access to shared buffer in such a way that the Producer doesn't try to insert data into the buffer when it is full and Consumer doesn't try to consume data from the buffer when it is empty.

Logic for the Producer-Consumer program

There is a shared object, a LinkedList of integers (note that LinkedList class implements Queue interface) which is used by both threads. There is a ProdClass which adds integers to the list and ConClass which retrieves those integers from the list. In the program looping is done for 5 times so there is a condition to break after iteration is done 5 times.

Logic here is that Producer puts one integer in the list and waits until the consumer consumes that integer, that's where wait/notify come into the picture. Producer puts one integer and then go to wait state, while notifying the other thread to wake up and vice versa and this is done with in a synchronized block.

Thus producer and consumer work sequentially where producer adds data and consumer retrieves it and so on.

Producer-Consumer Java program

import java.util.LinkedList;
import java.util.Queue;

public class ProdConDemo {

    public static void main(String[] args) {
        // This is the shared list shared between producer
        // and consumer.. LinkedList implements Queue interface
        Queue<Integer> sharedListObj = new LinkedList<Integer>();
        Thread t1 = new Thread(new ProdClass(sharedListObj), "ProdThread");
        Thread t2 = new Thread(new ConClass(sharedListObj), "ConThread");
        t1.start();
        t2.start(); 
    }
}

// Producer class
class ProdClass implements Runnable{
    Queue<Integer> sharedListObj;
    // Constructor
    ProdClass(Queue<Integer> sharedListObj){
        this.sharedListObj = sharedListObj;
    }
    @Override
    public void run() {
        int i = 0;
        while(true){
            synchronized (sharedListObj) {
                // While condition as mandated to avoid spurious wakeup
                while(sharedListObj.size() >= 1){
                    try {
                        sharedListObj.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                // Putting value in the list
                System.out.println("Adding to queue - " + Thread.currentThread().getName() 
                   + " " + ++i);
                sharedListObj.add(i);
                sharedListObj.notify();    
                // To get out of while(true) loop (running 5 times only)
                if(i > 4) break;
            }
        }
    }            
}

//Consumer class
class ConClass implements Runnable{
    Queue<Integer> sharedListObj;
    // Constructor
    ConClass(Queue<Integer> sharedListObj){
        this.sharedListObj = sharedListObj;
    }
    @Override
    public void run() {    
        while(true){
            synchronized (sharedListObj) {
                while(sharedListObj.size() < 1){
                    try {
                        sharedListObj.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }                    
                }
                int val = sharedListObj.remove();
                // Getting value from the list
                System.out.println("Getting from queue " + Thread.currentThread().getName() 
                   + " " + val);
                // To get out of while(true) loop
                if(val == 5) {
                    break;
                }
                sharedListObj.notify();        
                
            }
        }
    }
}

Output

Adding to queue - ProdThread 1
Getting from queue ConThread 1
Adding to queue - ProdThread 2
Getting from queue ConThread 2
Adding to queue - ProdThread 3
Getting from queue ConThread 3
Adding to queue - ProdThread 4
Getting from queue ConThread 4
Adding to queue - ProdThread 5
Getting from queue ConThread 5

That's all for this topic Producer-Consumer Java Program Using wait notify. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Print Odd-Even Numbers Using Threads And wait-notify - Java Program
  2. How to Create Deadlock in Java Multi-Threading - Java Program
  3. Setting And Getting Thread Name And Thread ID - Java Program
  4. Why wait(), notify() And notifyAll() Methods Are in Object Class And Not in Thread Class
  5. Synchronization in Java Multi-Threading

You may also like-

  1. Count Total Number of Times Each Character Appears in a String - Java Program
  2. How to Find All The Permutations of The Given String
  3. Matrix Multiplication - Java Program
  4. How to Read File From The Last Line in Java
  5. How to inject prototype scoped bean in singleton bean
  6. ThreadLocal class in Java
  7. Lambda expression in Java 8
  8. Difference between ArrayList and CopyOnWriteArrayList in Java

1 comment:

  1. Thanks nice explanation....Refer this blog for interview questions and answers https://adnjavainterview.blogspot.in/2017/08/producer-consumer-problem-solution.html

    ReplyDelete