import java.util.*; // the final version resolves the problem of the threads joining others and being deadlocked. public class ProducerConsumer5 { private static int[] buffer; private static int front, rear, size; private static Random g; private static Thread t1, t2, t3, t4, t5; private static boolean done; public static void main(String[] args) { buffer=new int[10]; front=0; rear=0; size=0; g=new Random(); done=false; Producer p1=new Producer("Producer 1"); Producer p2=new Producer("Producer 2"); Consumer c1=new Consumer("Consumer 1"); Consumer c2=new Consumer("Consumer 2"); Consumer c3=new Consumer("Consumer 3"); t1=new Thread(p1); t2=new Thread(p2); t3=new Thread(c1); t4=new Thread(c2); t5=new Thread(c3); t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); } public static class Producer implements Runnable { private String name; public Producer(String name){ this.name=name; } public void run() { int temp; while(!done) { try{ temp=g.nextInt(1000); System.out.println(name + " sleeping for " + temp); Thread.sleep(temp); } catch(InterruptedException e) { System.out.println(e); } while(size>=10) { // cannot produce, sleep temporarily System.out.println(name + " attempting to produce full buffer, forced to wait"); Thread.yield(); } // room to produce so do so temp=g.nextInt(10)+1; System.out.println("Producer " + name + " producing " + temp + " at " + rear); buffer[rear]=temp; rear++; if(rear==10) rear=0; // circular array, circle back around size++; } } } public static class Consumer implements Runnable { private String name; public Consumer(String name){ this.name=name; } public void run() { int temp; while(!done) // back to an infinite loop, let the threads run indefinitely { try{ temp=g.nextInt(1000); System.out.println(name + " sleeping for " + temp); Thread.sleep(temp); } catch(InterruptedException e) { System.out.println(e); } while(size==0) { // cannot consume, sleep temporarily System.out.println(name + " attempting to consume empty list, forced to wait"); Thread.yield(); } // something available, consume temp=buffer[front]; System.out.println("Consumer " + name + " consuming " + temp + " at " + front); front++; if(front==10) front=0; size--; } } } }