How to solve MULTIPLE producer consumer problem in java




Here come the time to answer very very important question from interview perspective. Interviewers tends to check how sound you are in threads inter communication. Because for solving this problem we got to use synchronization blocks, wait() and notify() method very cautiously. If you misplace synchronization block or any of the method, that may cause your program to go horribly wrong. So, before going into this question first i’ll recommend you to understand how to use synchronized blocks, wait() and notify() methods.


Logic is explained in comments in program

Full Program/sourceCode to How to solve MULTIPLE producer consumer and producer problem using wait() and notify() method> 
import java.util.LinkedList;
import java.util.List;


/**
* Producer Class.
*/
class Producer implements Runnable {

private List<Integer> sharedQueue;
private int maxSize=4; //maximum number of products which sharedQueue can hold at a time.
int productionSize=5; //Total no of items to be produced by each producer
int producerNo;
public Producer(List<Integer> sharedQueueint producerNo) {
     this.sharedQueuesharedQueue;
     this.producerNoproducerNo;
}

@Override
public void run() {
     for (int i = 1; i <= productionSizei++) { //produce products.
         try {
             produce(i);
         catch (InterruptedException e) {  e.printStackTrace(); }
     }
}

private void produce(int ithrows InterruptedException {
 
   synchronized (sharedQueue) {
      //if sharedQuey is full wait until consumer consumes.
      while (sharedQueue.size() == maxSize) {
             System.out.println(Thread.currentThread().getName()+", Queue is full, producerThread is waiting for "
                    "consumerThread to consume, sharedQueue's size= "+maxSize);
             sharedQueue.wait();
         }

      //Bcz each producer must produce unique product
             //Ex= producer0 will produce 1-5  and producer1 will produce 6-10 in random order
      int producedItem = (productionSize*producerNo)+ i;  
     
       System.out.println(Thread.currentThread().getName() +" Produced : "producedItem);
       sharedQueue.add(producedItem);
         Thread.sleep((long)(Math.random() * 1000));
         sharedQueue.notify();
     }
}
}

/**
* Consumer Class.
*/
class Consumer implements Runnable {
    private List<Integer> sharedQueue;
public Consumer(List<Integer> sharedQueue) {
     this.sharedQueuesharedQueue;
}
    @Override
public void run() {
     while (true) {
         try {
             consume();
             Thread.sleep(100);
         catch (InterruptedException e) {  e.printStackTrace(); }
     }
}

private void consume() throws InterruptedException {
  
   synchronized (sharedQueue) {
      //if sharedQuey is empty wait until producer produces.
      while (sharedQueue.size() == 0) {
          System.out.println(Thread.currentThread().getName()+", Queue is empty, consumerThread is waiting for "
                          "producerThread to produce, sharedQueue's size= 0");
             sharedQueue.wait();
         }

       Thread.sleep((long)(Math.random() * 2000));
         System.out.println(Thread.currentThread().getName()+", CONSUMED : "sharedQueue.remove(0));
         sharedQueue.notify();
     }
}
}

public class MULTIPLE_ProducerConsumerWaitNotify {

public static void main(String args[]) {
List<Integer> sharedQueuenew LinkedList<Integer>(); //Creating shared object
  
Producer producer0=new Producer(sharedQueue, 0);
Consumer consumer0=new Consumer(sharedQueue);

     Thread producerThread0new Thread(producer0"ProducerThread0");
     Thread consumerThread0new Thread(consumer0"ConsumerThread0");
     producerThread0.start();
     consumerThread0.start();
    
     System.out.println("MID");
    
Producer producer1=new Producer(sharedQueue, 1);
Consumer consumer1=new Consumer(sharedQueue);

     Thread producerThread1new Thread(producer1"ProducerThread1");
     Thread consumerThread1new Thread(consumer1"ConsumerThread1");
     producerThread1.start();
     consumerThread1.start();
}
}

/*OUTPUT

MID
ProducerThread0 Produced : 1
ProducerThread0 Produced : 2
ConsumerThread1, CONSUMED : 1
ProducerThread1 Produced : 6
ProducerThread1 Produced : 7
ProducerThread1 Produced : 8
ProducerThread1, Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 4
ConsumerThread0, CONSUMED : 2
ProducerThread1 Produced : 9
ProducerThread1, Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 4
ConsumerThread0, CONSUMED : 6
ConsumerThread1, CONSUMED : 7
ProducerThread0 Produced : 3
ProducerThread0 Produced : 4
ProducerThread0, Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 4
ConsumerThread1, CONSUMED : 8
ConsumerThread0, CONSUMED : 9
ProducerThread1 Produced : 10
ConsumerThread0, CONSUMED : 3
ConsumerThread1, CONSUMED : 4
ProducerThread0 Produced : 5
ConsumerThread1, CONSUMED : 10
ConsumerThread0, CONSUMED : 5
ConsumerThread1, Queue is empty, consumerThread is waiting for producerThread to produce, sharedQueue's size= 0
ConsumerThread0, Queue is empty, consumerThread is waiting for producerThread to produce, sharedQueue's size= 0

*/


RELATED LINKS>

Consumer Producer problem solution using different techniques >
Solve Consumer Producer problem by using wait() and notify() methods in multithreading

solve Consumer Producer problem by using wait() and notify() methods, where consumer can consume only when production is over


How to solve Consumer Producer problem without using wait() and notify() methods, where consumer can consume only when production is over.


BlockingQueue > 

Solve Consumer Producer problem by using BlockingQueue in multithreading


Custom implementation of LinkedBlockingQueue class which implements BlockingQueue interface



Interviews >

THREADS - Top 80 interview questions and answers (detailed explanation with programs) Set-1 > Q1- Q60 

THREADS - Top 80 interview questions and answers, important interview OUTPUT questions and answers, Set-2 > Q61- Q80




eEdit
Must read for you :