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.
- Refer Producer-Consumer Java program using ArrayBlockingQueue to see how to solve producer-consumer problem using ArrayBlockingQueue.
This program makes use of inter-thread communication using wait, notify, notifyAll. 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.
- Refer Why wait(), notify() and notifyAll() must be called inside a synchronized method or block to know more about the topic.
Thus producer and consumer work sequentially where producer adds data and consumer retrieves it and so on.
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 using wait notify. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
You may also like -