// -------- Shared Buffer Class -------- class Buffer { private int value; private boolean hasValue = false; // Producer puts value synchronized void put(int value) { while (hasValue) { try { wait(); // wait if buffer is full } catch (InterruptedException e) { System.out.println(e); } } this.value = value; hasValue = true; System.out.println("Produced: " + value); notify(); // notify consumer } // Consumer gets value synchronized int get() { while (!hasValue) { try { wait(); // wait if buffer is empty } catch (InterruptedException e) { System.out.println(e); } } System.out.println("Consumed: " + value); hasValue = false; notify(); // notify producer return value; } } // -------- Producer Thread -------- class Producer extends Thread { Buffer buffer; Producer(Buffer buffer) { this.buffer = buffer; } public void run() { int i = 1; while (true) { buffer.put(i++); try { Thread.sleep(500); } catch (InterruptedException e) { System.out.println(e); } } } } // -------- Consumer Thread -------- class Consumer extends Thread { Buffer buffer; Consumer(Buffer buffer) { this.buffer = buffer; } public void run() { while (true) { buffer.get(); try { Thread.sleep(500); } catch (InterruptedException e) { System.out.println(e); } } } } // -------- Main Class -------- public class ProducerConsumerDemo { public static void main(String[] args) { Buffer buffer = new Buffer(); Producer producer = new Producer(buffer); Consumer consumer = new Consumer(buffer); producer.start(); consumer.start(); } }