/* * This code is wrong. */ import java.util.ArrayList; class BoundedBufferNotify { private char [] buffer; private int head, tail; BoundedBufferNotify(int capacity) { buffer = new char[capacity]; head = tail = 0; } private boolean buffer_full() { return (tail+1-head) % buffer.length == 0; } private boolean buffer_empty() { return head == tail; } public synchronized void produce(char i) throws InterruptedException { while (buffer_full()) this.wait(); buffer[head] = i; head = (head + 1) % buffer.length; this.notify(); // *WRONG * } public synchronized char consume() throws InterruptedException { while (buffer_empty()) this.wait(); char item = buffer[tail]; tail = (tail + 1) % buffer.length; this.notify(); // *WRONG * return item; } public static void main(String []av) throws InterruptedException { if (av.length < 2) System.out.println("Usage: \n"); final int CONSUMERS = Integer.parseInt(av[0]); final int PRODUCERS = Integer.parseInt(av[1]); final int items_per_consumer = PRODUCERS * 1000; final int items_per_producer = (items_per_consumer * CONSUMERS) / PRODUCERS; final BoundedBufferNotify buffer = new BoundedBufferNotify(4); final ArrayList threads = new ArrayList(); final Runnable consumer = new Runnable() { public void run() { try { for (int i = 0; i < items_per_consumer; i++) buffer.consume(); System.out.println("Consumer " + Thread.currentThread() + " done consuming #" + items_per_consumer); } catch (InterruptedException e) { } } }; final Runnable producer = new Runnable() { public void run() { try { for (int i = 0; i < items_per_producer; i++) buffer.produce((char)('A' + (int)(26 * Math.random()))); System.out.println("Producer " + Thread.currentThread() + " done producing #" + items_per_producer); } catch (InterruptedException e) { } } }; for (int i = 0; i < PRODUCERS; i++) threads.add(new Thread(producer)); for (int i = 0; i < CONSUMERS; i++) threads.add(new Thread(consumer)); for (Thread t : threads) t.start(); for (Thread t : threads) t.join(); } }