Thursday 24 October 2013

Java Producer-Consumer example using wait and notify

An example in java for Producer-Consumer problem using wait() and notify() :
/**
 * 
 * @author vikky.agrawal
 */

public class Threads {

 public static void main(String args[]) {

  Semaphore mutex = new Semaphore();
  Producer producer = new Producer(mutex);
  Consumer consumer = new Consumer(mutex);
  System.out.println("Main starts");
  producer.start();
  consumer.start();

  try {
   consumer.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("Main Stop");
 }
}

class Consumer extends Thread {

 Semaphore mutex;

 Consumer(Semaphore mutex) {

  super("Consumer");

  this.mutex = mutex;

 }

 @Override
 public void run() {

  for (int i = 0; i < 50; i++) {
   try {
    sleep(1000);
    mutex.down();
   } catch (InterruptedException e) {
    e.printStackTrace();

   }
  }
 }
}

class Producer extends Thread {

 Semaphore mutex;

 Producer(Semaphore mutex) {
  super("producer");
  this.mutex = mutex;
 }

 @Override
 public void run() {

  for (int i = 0; i < 100; i++) {
   mutex.up();
   try {
    sleep(10);
   } catch (InterruptedException e) {

   }
  }
 }
}

class Semaphore {

 static int value = 0;
 boolean available = false;

 public synchronized void down() {

  while (!available) {
   try {
    wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   // System.out.println("Consumer woke up from waiting");
  }
  value--;
  System.out.println("Consumed now value : " + value);
  available = false;
  notify();
 }

 public synchronized void up() {

  while (available) {
   try {
    wait();
    // System.out.println("Producer Got a notification and available is now: "+available);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   // System.out.println("Producer woke up from waiting");
  }
  value++;
  System.out.println("Produced now value :" + value);
  available = true;
  notify();
 }
}

2 comments:

  1. hello mr.vikky agarwal,
    I had a doubt that i mentioned below program is suitable for your algorthim,pls reply me sir.




    import java.util.*;
    import java.io.*;

    // We would like to synchronize producer and consumer so that
    // producer puts a number in the buffer, then the consumer takes it
    // out, then the producer puts another number, and so on.

    // This solution provides the right behaviour
    // We have changed the class Buffer to include wait() and notify()
    // We also have changed the producer and cinsumer classes
    // slightly to handle a new exception

    public class ConsumerProducerGood {

    public static void main (String [] args) {
    Buffer buf = new Buffer();

    // create new threads
    Thread prod = new Producer(10, buf);
    Thread cons = new Consumer(10, buf);

    // starting threads
    prod.start();
    cons.start();

    // Wait for the threads to finish
    try {
    prod.join();
    cons.join();
    } catch (InterruptedException e) {return;}
    }

    }

    class Buffer {
    private int contents;
    private boolean empty = true;

    public synchronized void put (int i) throws InterruptedException {
    while (empty == false) { //wait till the buffer becomes empty
    try { wait(); }
    catch (InterruptedException e) {throw e;}
    }
    contents = i;
    empty = false;
    System.out.println("Producer: put..." + i);
    notify();
    }

    public synchronized int get () throws InterruptedException {
    while (empty == true) { //wait till something appears in the buffer
    try { wait(); }
    catch (InterruptedException e) {throw e;}
    }
    empty = true;
    notify();
    int val = contents;
    System.out.println("Consumer: got..." + val);
    return val;
    }
    }


    public class Producer extends Thread {
    private int n;
    private Buffer prodBuf;

    public Producer (int m, Buffer buf) {
    n = m;
    prodBuf = buf;
    }

    public void run() {
    for (int i = 0; i < n; i++) {
    try {
    Thread.sleep( (int) Math.random() * 100); // sleep for a randomly chosen time
    } catch (InterruptedException e) {return;}

    try {
    prodBuf.put(i + 1); //starting from 1, not 0
    } catch (InterruptedException e) {return;}

    }
    }
    }

    public class Consumer extends Thread {
    private int n;
    private Buffer consBuf;

    public Consumer (int m, Buffer buf) {
    n = m;
    consBuf = buf;
    }

    public void run() {
    int value;
    for (int i = 0; i < n; i++) {
    try {
    value = consBuf.get();
    } catch (InterruptedException e) {return;}
    try {
    Thread.sleep( (int) Math.random() * 100); // sleep for a randomly chosen time
    } catch (InterruptedException e) {return;}

    }
    }
    }








    ReplyDelete
    Replies
    1. First of all don't call me sir :)

      What is your doubt?
      I couldn't go through the whole program but if you ask me your doubt specifically then I can try to help.!

      Delete