// producer consumer example import java.util.ArrayList; interface Shared { // status indicators: all non-blocking: int capacity(); // max number of shared resources pool can hold. int waiting(); // number of resources ready to be consumed int busy(); // number of resources being consumed. int empty(); // number of available slots available to producer // produces resource, blocks if empty()<1, returns id uniquely identifying // this resource as part of the pool: int produce(Resource R); // Attempt to consume resource, blocks if none are available, returns // resource id, which can be acquired by get. int consume(); // when finished with resource, call (non-blocking) void finished(int rid); // returns resource indicated by resource id, returns null if not valid. // this is always a non-blocking call. Resource getresource(int rid); // blocks calling thread until all resources in pool have been consumed // (finished). returns total number of resources consumed in life time of // resource pool. int joinall(); } // producers have unlimited capacity. class Foodfactory implements Shared // resources are food (strings) { int max; int waiting = 0; int busy = 0; public int capacity() { return max; } public int waiting() { return waiting; } public int busy() { return busy; } public int empty() {return max - waiting - busy; } ArrayList Slots; ArrayList Status; final int EMPTY = 0; final int WAITING = 1; final int BUSY = 2; final int INVALID = -1; int nextwaiting = INVALID; // next resource waiting to be consumed public Foodfactory(int m) // constructor { max = m; Slots = new ArrayList(); Status = new ArrayList(); } public synchronized int produce(String food) { int rid = 0; try { while (empty()<1) { System.out.println(this+": production of "+food+" blocked"); wait(); } rid = Status.size(); Slots.add(food); Status.add(WAITING); waiting++; if (waiting==1) nextwaiting = rid; // FIFO QUEUE notifyAll(); } catch (InterruptedException ie) { return INVALID; } return rid; }// produce public synchronized int consume() { int rid = 0; try { while (waiting<1) wait(); waiting--; // take food! busy++; rid = nextwaiting; // System.out.println("nextwaiting:"+nextwaiting); Status.set(nextwaiting,BUSY); // reset nextwaiting if (waiting==0) nextwaiting = INVALID; else { while (nextwaiting=Slots.size() || Status.get(rid)!=BUSY) return; Status.set(rid,EMPTY); busy--; } // returns resource indicated by resource id, returns null if not valid. // this is always a non-blocking call. public synchronized String getresource(int rid) { if (rid pool; public cook(Shared p) { pool=p; } String[] F = {"cupcake","crabcake","cookie","ice cream","pizza","burrito","taco","hot dog","cheeseburger","lobster","bacon and eggs","fried chicken","blt"}; public void run() { for(String f:F) pool.produce(f); pool.joinall(); // don't terminate until all's eaten. } }// cook class customer implements Runnable { Shared pool; public customer(Shared p) { pool=p; } public boolean stop = false; public void run() { try{ while (!stop) { int rid = pool.consume(); String food = pool.getresource(rid); System.out.println(this+": eating "+food); int ms = (int)(Math.random()*10000); // random delay try{Thread.sleep(ms);} catch (Exception e) {} // EAT pool.finished(rid); } } catch (Exception ie) {} } }//customer public class prodcon3 { public static void main(String[] av) throws Exception { Shared pool = new Foodfactory(8); Thread p1 = new Thread(new cook(pool)); Thread c1 = new Thread(new customer(pool)); Thread c2 = new Thread(new customer(pool)); p1.start(); c1.start(); c2.start(); p1.join(); // c1.interrupt(); // c2.interrupt(); System.exit(0); // kills all threads } }