producer-consumer problem in java 8

Producer-consumer Problem is one of the classic problems of multi-threading and also frequently asked in some of the interviews along with  Print Odd Even Numbers Using two threads and  Print 1,2,3 Using 3 Threads

In this blog, I will explain how to write a java program using inter-thread communication. In short using wait() and notify() methods. 



Problem Statement

There is one queue of n capacity. This queue is shared between producer and consumer. n is the capacity and for this blog, I will take n = 5. 

Producer adds a block to the queue when queue size is less than its capacity. Consumer will consume from the same queue when queue size is greater than 0. Using multi-threading, we need to write java program with thread synchronization. 

Approach


If you have gone through earlier blogs to Print Odd Even Numbers Using two threads and  Print 1,2,3 Using 3 Threads , you will notice a pattern which can be applied here as well. Take sometime to understand the pattern. 


Let us create two threads initially denoting producer and consumer. You can take the capacity from program arguments. I hardcoded this value to 5. 



public class Control {
public static void main(String[] args) {
ProducerConsumer producerConsumer = new ProducerConsumer(5);
Thread producer = new Thread(new Task(true, producerConsumer), "Producer ");
Thread consumer = new Thread(new Task(false, producerConsumer), "Consumer ");
producer.start();
consumer.start();
}
}
view raw PCControl.java hosted with ❀ by GitHub


When the queue is empty(), we need to produce to it. Here, producer will get a head start as queue is empty and consumer will be waiting for its turn till producer finishes producing to the queue.

Once producer finishes, consumer will start consuming and producer will be waiting till the queue is emptied. This will go on based on the condition in the while loop.

class Task implements Runnable {
boolean isProducer;
ProducerConsumer producerConsumer;
public Task(boolean isProducer, ProducerConsumer producerConsumer) {
this.isProducer = isProducer;
this.producerConsumer = producerConsumer;
}
@Override
public void run() {
try {
while (true) {
if (isProducer) {
producerConsumer.produce();
} else {
producerConsumer.consume();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
view raw PCTask.java hosted with ❀ by GitHub

Here, the producer thread will only execute produce() method and consumer will only execute consumer() method of ProducerConsumer Object. 

class ProducerConsumer {
Queue<Integer> list;
int capacity;
volatile int value = 1;
public ProducerConsumer(int capacity) {
this.capacity = capacity;
list = new LinkedList<>();
}
public synchronized void produce() throws InterruptedException {
while (capacity == list.size()) {
wait();
}
System.out.println(Thread.currentThread().getName() + "Produced : " + value);
list.add(value++);
notify();
Thread.sleep(1000);
}
public synchronized void consume() throws InterruptedException {
while (0 == list.size()) {
wait();
}
System.out.println(Thread.currentThread().getName() + "Consumed : " + list.poll());
value--;
notify();
Thread.sleep(1000);
}
}
view raw PC.java hosted with ❀ by GitHub

Feel free to experiment as there are lot of versions of this problem. Try it out with multiple consumers and experiment with waiting logic. 

Output


producer consumer problem java using wait notify


Post a Comment