public class ProducerConsumer1 {
	public static void main(String args[]) {
		Buffer b = new Buffer();
		Producer p = new Producer(b);
		Consumer c = new Consumer(b);
		
		p.start();
		c.start();
		}
	}
	
class Producer extends Thread {
	private Buffer b;
	
	public Producer(Buffer b){this.b = b;}
	
	public void run() {
		for(int i=0;i<12;i++) {
			try {
				Thread.sleep((int)(Math.random() * 3000));
				}
			catch(InterruptedException e) {
				System.err.println(e.toString());
				}
			b.put(i);
			System.out.println("Producer set buffer to " + i);
			}
		}	
	}
	
class Consumer extends Thread {
	private Buffer b;
	
	public Consumer(Buffer b){this.b = b;}
	
	public void run() {
		for(int i=0;i<12;i++) {
			try {
				Thread.sleep((int)(Math.random() * 3000));
				}
			catch(InterruptedException e) {
				System.err.println(e.toString());
				}
			System.out.println("Consumer retrived " + b.get());
			}
		}	
	}
	
class Buffer {
	private int value;
	private boolean empty = true;
	
	public synchronized void put(int val) {
		while(!empty) {
			try{
				wait();
				}
			catch(InterruptedException e) {
				System.err.println("Exception:" + e.toString()); 
				}
			}
		value = val;
		empty = false;
		notify();
		}
	
	public synchronized int get() {
		int value;
		
		while(empty) {
			try{
				wait();
				}
			catch(InterruptedException e) {
				System.err.println("Exception:" + e.toString()); 
				}
			}
		value = this.value;
		empty = true;
		notify();
		return value;
		}
	}