import java.util.*; class Counter { private int count; public Counter() { count = 0; } public void increment() { ++count; } public void decrement() { --count; } public int get() { return count; } } class Queue { // The shared buffer: static Queue store = new Queue(); private LinkedList data = new LinkedList(); public void put(Object o) { data.addFirst(o); } public Object get() { return data.removeLast(); } public int size() { return data.size(); } } class Producer extends Thread { private static Random numbers = new Random(); private Counter counter; Producer(String id, Counter counter) { super(id); this.counter = counter; } int genNumber() { // Generate a random number in (0, 1000) return (int)(numbers.nextDouble()*1000); } public void run() { counter.increment(); // Generate some elements for the Queue for (int i = 0; i < 8; ++i) { int number = genNumber(); System.out.println(getName() + " producing " + number); synchronized(Queue.store) { Queue.store.put(new Integer(number)); Queue.store.notify(); } } synchronized(Queue.store) { // Prevent deadlock for multiple consumers counter.decrement(); Queue.store.notifyAll(); } System.out.println("\t" + getName() + " finished"); } } class Consumer extends Thread { private Counter counter; Consumer(String id, Counter counter) { super(id); this.counter = counter; } public void run() { for (;;) { synchronized(Queue.store) { while (Queue.store.size() == 0) { if (counter.get() == 0) { // Producers are done and queue is empty System.out.println("\t" + getName() + " terminating"); return; } try { Queue.store.wait(); } catch (InterruptedException x) {} } System.out.println(getName() + " consuming " + Queue.store.get()); } } } } class CommTest2 { public static void main(String[] args) { // Start Producers Counter counter = new Counter(); new Producer("Producer1", counter).start(); new Producer("Producer2", counter).start(); // Start Consumers new Consumer("Consumer1", counter).start(); new Consumer("Consumer2", counter).start(); } } /* Output: Producer1 producing 386 Producer1 producing 240 Producer1 producing 982 Producer1 producing 453 Producer1 producing 878 Producer1 producing 228 Producer1 producing 245 Producer2 producing 189 Consumer1 consuming 386 Consumer2 consuming 240 Producer2 producing 740 Consumer1 consuming 982 Consumer2 consuming 453 Producer2 producing 264 Consumer1 consuming 878 Consumer2 consuming 228 Producer2 producing 686 Consumer1 consuming 189 Consumer2 consuming 740 Producer2 producing 761 Consumer1 consuming 264 Consumer2 consuming 686 Producer2 producing 586 Consumer1 consuming 761 Producer2 producing 847 Consumer1 consuming 586 Producer2 producing 161 Consumer1 consuming 847 Consumer1 consuming 161 Producer2 finished Consumer1 consuming 245 Producer1 producing 329 Consumer2 consuming 329 Consumer1 terminating Consumer2 terminating Producer1 finished */ End of Listing