import java.util.*; // same as ProducerConsumer with one change. The Consumer now will yield its time (using yield) // if it tries to consume an element in buffer that has not yet been produced. This is the case if front>=rear. public class ProducerConsumer2 { private static int[] buffer; private static int front, rear; 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; 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); } temp=g.nextInt(10)+1; System.out.println("Producer " + name + " producing " + temp + " at " + rear); buffer[rear]=temp; rear++; } } } public static class Consumer implements Runnable { private String name; public Consumer(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); } if(front>=rear) { // if true, we have consumed more than has been produced, must wait System.out.println(name + " attempting to consume empty list, forced to yield"); // inform user try{ if(g.nextInt(2)==1) t1.join(); else t2.join(); } catch(InterruptedException e) { System.out.println(e); } } temp=buffer[front]; System.out.println("Consumer " + name + " consuming " + temp + " at " + front); front++; } } } } // running this program will show that no Consumer will consume a value of 0 but it does not fix the problem // of a Producer placing a value into a buffer in the wrong location (once rear >= 10)