Producer Consumer Problem Solution Using Wait and Notify

Posted By Navin Purohit | 16-Jan-2018

 Producer-Consumer problem solution using wait and notify in Multithreading

 

In multi-threaded programming, we frequently encountered a producer-consumer problem which is also known as a bounded-buffer problem. If we do not implement it correctly, it creates mess in our application. We need to take care that consumer not consumed before producer produced items, in such scenarios it hard to debug and reproduce the anomalies.

 

In this blog, I will solve the producer-consumer problem using wait and notify. Before we jump into solution first understand the problem of producer-consumer.

 

Problem :

In producer-consumer problem, producer won’t try to add data into buffer once it full and the consumer won’t consume after buffer empty. The consumer will know when data entered into the buffer for consuming and producer must stop producing when consumption rate is slow and the buffer is filled.

 

Solution:

To solve producer consumer problem, We need to take care few things like producer stop producing by either go to sleep or discard data. And when consumer consumes the item from the buffer, a notification goes to the producer that it can start producing again. In the same way, the consumer goes to sleep when the buffer is empty and when producer produces any item, a notification goes to the consumer that now it can start consuming. To implement above scenarios, in this blog we are using wait and notify. Let's see how can we achieve this solution.

 

 

import java.util.LinkedList;

public class ThreadDemo
{
	public static void main(String[] args) throws InterruptedException
	{
		final ProducerConsumer pc = new ProducerConsumer();

		// Create producer thread
		Thread t1 = new Thread(new Runnable()
		{
			@Override
			public void run()
			{
				try
				{
					pc.produce();
				}
				catch(InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		});

		// Create consumer thread
		Thread t2 = new Thread(new Runnable()
		{
			@Override
			public void run()
			{
				try
				{
					pc.consume();
				}
				catch(InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		});

		t1.start();
		t2.start();

		t1.join();
		t2.join();
	}

	public static class  ProducerConsumer
	{
		LinkedList<Integer> list = new LinkedList<>();
		int capacity = 2;

		public void produce() throws InterruptedException
		{
			int value = 0;
			while (true)
			{
				synchronized (this)
				{
					while (list.size()==capacity)
						wait();

					System.out.println("Producer produced-"+ value);

					list.add(value++);
					notify();
					Thread.sleep(1000);
				}
			}
		}

		public void consume() throws InterruptedException
		{
			while (true)
			{
				synchronized (this)
				{
					while (list.size()==0)
						wait();

					int val = list.removeFirst();

					System.out.println("Consumer consumed-"+ val);

					notify();
					Thread.sleep(1000);
				}
			}
		}
	}
}

 

Explanation:-

 

1. In ProducerConsumer class, a shared LinkedList which have a capacity of 2 in which producer add items and consumer consume it.

2. In producer method above, the value is initialized as 0. Inside this method, we have an infinite outer loop which contains synchronized block which ensures that at a time only producer or consumer thread runs. The inner loop checks the capacity of a list, if list if full then it gives up the lock on the synchronized block and goes to waiting state. If the list is empty then it adds the item to the list and notifies consumer that now it can start consuming from the shared list.

3. In consumer method above, we again have an infinite outer loop which checks/consume a value from the list. Same as producer method, inner loop checks if the list is empty. If a list is empty then it releases lock and tells producer that please producer more items. And if the list is not empty then it removes item from list.

4. We use notify() to tell other waiting thread that now it can take the lock and start processing. Sleep() method used here just for better understanding.

 

In my next blog, we will see the solution of the producer-consumer problem using a blocking queue. 

 

  

Request for Proposal

Recaptcha is required.

Sending message..