Friday, September 18, 2015

Java Concurrency Model - Part I - Producer Consumer Problem

Note: Get the source code from https://github.com/sommukhopadhyay/ProducerConsumer

As i was getting ready to teach Java Concurrency Model to my students, I have come up with few examples which i would like to share with you. The first example is about Producer Consumer problem. Here is the solution to this using wait and notify. In the next two posts we will see about CountDownLatch and FutureTask respectively.

Class ProducerConsumerQueue

package com.somitsolutions.training.java.ProducerConsumerProblem;

import java.util.Vector;

public class ProducerConsumerQueue {
 Vector<Integer> sharedQueue = new Vector<Integer>();
 private final int SIZE = 4;
 
 public ProducerConsumerQueue(){
 }
 
 public int getSIZE(){
  return SIZE;
 }
 
 public synchronized void produce(int i) throws InterruptedException{
  while(sharedQueue.size() == SIZE){
   System.out.println("Queue is full" + Thread.currentThread() + "is waiting, size = " + sharedQueue.size());
   wait();
  }
  sharedQueue.add(i);
  notifyAll();
 }
 
 public synchronized int consume() throws InterruptedException{
  while(sharedQueue.isEmpty()){
   
    System.out.println("Queue is empty " + Thread.currentThread().getName()
                        + " is waiting , size: " + sharedQueue.size());
    wait();
   }
  int retVal = sharedQueue.remove(0);
  notifyAll();
  return retVal;
 }
}

Class Producer

package com.somitsolutions.training.java.ProducerConsumerProblem;


public class Producer implements Runnable{
 private final ProducerConsumerQueue sharedQueue;
 private final int SIZE;
 
 public Producer(ProducerConsumerQueue queue){
  sharedQueue = queue;
  this.SIZE = sharedQueue.getSIZE();
 }
 @Override
 public void run() {
  // TODO Auto-generated method stub
  for (int i = 0; i<7; i++){
   System.out.println("Produced: " + i);
   try{
    sharedQueue.produce(i);
    Thread.sleep(100);
   }
   catch (InterruptedException ex){
    
   }
  }
 }

}

Class Consumer

package com.somitsolutions.training.java.ProducerConsumerProblem;


public class Consumer implements Runnable{
 private final ProducerConsumerQueue sharedQueue;
 private final int SIZE;
 
 public Consumer(ProducerConsumerQueue queue){
  sharedQueue = queue;
  this.SIZE = sharedQueue.getSIZE();
 }
 @Override
 public void run() {
  // TODO Auto-generated method stub
  while (true){
   try{
    int val = sharedQueue.consume();
    System.out.println("Consumed:" + val);
    Thread.sleep(50); 
   }
   catch (InterruptedException ex){ 
   }
  }
 }

}

Class Main

package com.somitsolutions.training.java.ProducerConsumerProblem;

public class Main {
 public static void main(String[] args){
  ProducerConsumerQueue sharedQueue = new ProducerConsumerQueue();
  Thread prodThread = new Thread(new Producer(sharedQueue), "Producer");
        Thread consThread = new Thread(new Consumer(sharedQueue), "Consumer");
        prodThread.start();
        consThread.start();
 }
}

No comments: