Producer consumer problem in Java

Problem: Implement producer consumer problem solution in Java. Producer consumer problem is basic multi-threading problem which will give idea about concurrency and inter-thread communication in Java.

Producer produces items and puts it on to a shared queue. Producer should wait till consumer consumes this item from queue. Once consumer consumes item from queue, it notifies producer and waits for producer to put item on to the queue. At any given point of time, queue has max one item on it.

Producer and consumer communicate with each other using wait and notify mechanism. Java uses synchronized, wait and notify for inter-thread communication. We will use wait and notify to implement producer consumer problem.

wait() – Causes the current thread to wait until another thread invokes the notify()  method for this object.

notify() – Wakes up a single thread that is waiting on this object’s monitor.

synchronized – synchronized keyword is used to get lock on an object.

Java code:

Let us solution for producer consumer problem in Java.

In following program, producer produces 10 items and consumer consumes those 10 items. Read the comments for more understanding.

package com.javafries.thread;

/**
 * Shared queue.
 * Producer will put item on this queue
 * Consumer will consume item from this queue.
 *
 */
class SharedQueue {
	private boolean isConsumed = true;

	public void put(int itemNo) throws InterruptedException {
		
		// Lock on queue
		synchronized (this) {
			
			// Wait until item is consumed.
			if (!isConsumed)
				wait();

			System.out.println("Item produced: " + itemNo);
			isConsumed = false;
			
			// Notify consumer that item has been produced.
			notify();
		}
	}

	public void get(int itemNo) throws InterruptedException {
		
		// Lock on queue
		synchronized (this) {
			
			// Wait until item is produced.
			if (isConsumed)
				wait();

			System.out.println("Item consumed : " + itemNo);
			isConsumed = true;
			
			// Notify producer that item has been consumed.
			notify();
		}
	}
}

class Consumer implements Runnable {
	private SharedQueue queue;

	public Consumer(SharedQueue queue) {
		this.queue = queue;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				queue.get(i);
			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}
		}
	}
}

class Producer implements Runnable {
	private SharedQueue queue;

	public Producer(SharedQueue queue) {
		this.queue = queue;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				queue.put(i);
			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}
		}
	}
}

public class ProducerConsumerSolution {
	public static void main(String[] args) {
		SharedQueue sharedQueue = new SharedQueue();
		
		// Create and start producer and consumer threads.
		// Same queue is shared with both producer and consumer.
		new Thread(new Consumer(sharedQueue)).start();
		new Thread(new Producer(sharedQueue)).start();
	}
}

Output:

Item produced: 0
Item consumed : 0
Item produced: 1
Item consumed : 1
Item produced: 2
Item consumed : 2
Item produced: 3
Item consumed : 3
Item produced: 4
Item consumed : 4
Item produced: 5
Item consumed : 5
Item produced: 6
Item consumed : 6
Item produced: 7
Item consumed : 7
Item produced: 8
Item consumed : 8
Item produced: 9
Item consumed : 9

Notice that, an item is consumed only when it is produced. Once an item is produced, producer waits for the item to be consumed.

I hope you liked and understood above solution for producer consumer problem.
Your questions and comments are most welcome.

Enjoy threading.

Leave a Reply