import java.util.concurrent.locks.*; class Restaurant9 { HeatingTable table; Restaurant9(String[] args) { table = new HeatingTable(3,Integer.parseInt(args[0])); int numChefs = Integer.parseInt(args[1]); int numWaiters = Integer.parseInt(args[2]), w = numWaiters; Thread [] t = new Thread[numChefs+numWaiters]; while (numWaiters-- > 0) (t[numWaiters]= new Waiter(table,numWaiters+1 )).start(); while (numChefs-- > 0) (t[numChefs + w]= new Chef(table,numChefs+1)).start(); for( Thread tt : t) try{tt.join();}catch (Exception e){}; // The main-hread is now 'alone' Do other stuff } public static void main(String[] args) { Restaurant rest; if (args.length != 3) { System.out.println("use: >java Restaurant <#Chefs> <#Waiters>"); }else{ rest = new Restaurant(args); System.out.println("The System TERMINATES"); } } // end main } class HeatingTable{ // Monitor int numOnTable = 0; // Invariant holds initielt int numProduced = 0; // Invariant holds initielt final int MAX_ON_TABLE ; final int NUM_TO_BE_MADE; // INVARIANTS 1. 0 <= numOnTable <= MAX_ON_TABLE // 2. numPlatesProduced <= NUM_TO_BE_MADE HeatingTable(int maxOn, int max) { MAX_ON_TABLE = maxOn; NUM_TO_BE_MADE = max; } final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); public boolean putPlate(Chef c) throws InterruptedException { lock.lock(); try { while (numOnTable == MAX_ON_TABLE && numProduced < NUM_TO_BE_MADE) { System.out.println("Kokk "+c.ind+ " WAITING to make a dish"); notFull.await(); System.out.println("Kokk "+c.ind+ " LEFT QUEUE "); } if (numProduced < NUM_TO_BE_MADE) { numProduced++; c.dishNum = numProduced; numOnTable++; System.out.println("Kokk number "+ c.ind+" makes plate num:" + c.dishNum ); notEmpty.signal(); if (numProduced == NUM_TO_BE_MADE) { // If I produced the last plate, notEmpty.signalAll(); // tell Kokk to stop waiting and terminate notFull.signalAll(); // Not more to wait for, Waiters serve last plate(s) return false; } return true; } else { return false;} } finally { lock.unlock(); } } // end put public boolean getPlate(Waiter w) throws InterruptedException { lock.lock(); try { while (numOnTable == 0 && numProduced < NUM_TO_BE_MADE ) { System.out.println("Kelner " + w.ind +" WAITING to serve a dish" ); notEmpty.await(); System.out.println("Kelner " + w.ind +" LEFT QUEUE" ); } if (numOnTable > 0) { numOnTable--; System.out.println("Kelner number "+ w.ind +" serves plate num:" + (numProduced-numOnTable) ); notFull.signal(); return true; } else { return false;} } finally { lock.unlock(); } } // end get } class Chef extends Thread { HeatingTable sharedTable; int ind; int dishNum; Chef(HeatingTable shared, int ind) { sharedTable = shared; this.ind = ind; } public void run() { try { while (sharedTable.putPlate(this)) { sleep((long) (1000 * Math.random())); } } catch (InterruptedException e) {} // Kokk has finished System.out.println("Kokk number"+ind+" finished: "); } } // end Chef class Waiter extends Thread { HeatingTable sharedTable; int ind; Waiter(HeatingTable shared, int ind) { sharedTable = shared; this.ind = ind; } public void run() { try { while ((sharedTable.getPlate(this))){ sleep((long) (1000 * Math.random())); } } catch (InterruptedException e) {} // This Waiteren has finished System.out.println("Kelner number " + ind+" finished: "); } } // end Waiter