Producer-Consumer problem is a very common question related to threads. Following is a simple solution to the problem. QueueClass represents the queue which both the Producer and Consumer has to access. The critical methods in the QueueClass - add() and remove() are synchronized in order to maintain the status quo between the Producer and Consumer threads.
- import java.util.List;
- import java.util.ArrayList;
- public class ProducerConsumerTest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- QueueClass q = new QueueClass();
- Producer p = new Producer(q, 10);
- Consumer c = new Consumer(q, 10);
- Thread t1 = new Thread(p);
- Thread t2 = new Thread(c);
- c.setpThread(t1);
- t1.start();
- t2.start();
- }
- }
- class Producer implements Runnable {
- QueueClass q;
- int size;
- Producer(QueueClass q, int size) {
- this.q = q;
- this.size = size;
- }
- public void run() {
- int index = -1;
- while(true) {
- q.add(new String("" + ++index));
- try {
- Thread.sleep(1000);
- }
- catch(InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- class Consumer implements Runnable {
- QueueClass q;
- int size;
- Thread pThread;
- public void setpThread(Thread pThread) {
- this.pThread = pThread;
- }
- Consumer(QueueClass q, int size) {
- this.q = q;
- this.size = size;
- }
- public void run() {
- while(true) {
- q.remove();
- try {
- Thread.sleep(1000);
- }
- catch(InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- class QueueClass {
- List<string> queue = new ArrayList<string>();
- int size = 10;
- public synchronized void add(String s) {
- if(getSize() < size) queue.add(s);
- System.out.println("Added: " + queue);
- try {
- if(getSize() >= size) {
- notifyAll();
- wait();
- }
- }
- catch(InterruptedException e) {
- e.printStackTrace();
- }
- }
- public synchronized void remove() {
- if(getSize() > 0) queue.remove(queue.size()-1);
- System.out.println("Removed: " + queue);
- try {
- if(getSize() <= 0) {
- notifyAll();
- wait();
- }
- }
- catch(InterruptedException e) {
- e.printStackTrace();
- }
- }
- public synchronized int getSize() {
- return queue.size();
- }
- }
- </string></string>