Thursday, 24 October 2013

Java Producer-Consumer example using wait and notify

An example in java for Producer-Consumer problem using wait() and notify() :

public class Threads {
    /**
     * @param args
     * @author vikky.agrawal
     */

    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