class HeatingTable2{ // A monitor int nosOnTable = 0; int nosProduced = 0; // Invariants holds initially final int TABLE_SIZE; final int NOS_TO_BE_MADE; // INVARIANTS: // 1) 0 <= nosOnTable <= TABLE_SIZE // 2) nosProduced <= NOS_TO_BE_MADE HeatingTable2(int maxOn, int max) { TABLE_SIZE = maxOn; NOS_TO_BE_MADE = max; } // Invariants holds initially as long as // parameters are none-negative public synchronized boolean putPlate(Chef c) { while (nosOnTable == TABLE_SIZE && nosProduced < NOS_TO_BE_MADE) { try { // The while test holds here meaning // that a Kokk should but can not // make a dish, because the table is full System.out.println("Kokk "+c.ind+ " VENTER paa aa lage en tallerken"); wait(); } catch (InterruptedException e) { } } // one or both of the loop conditions are now false if (nosProduced < NOS_TO_BE_MADE) { // nosOnTable < TABLE_SIZE // Hence OK to increase nosOnTable nosOnTable++; // nosProduced < NOS_TO_BE MADE // Hence OK to increase nosProduced: nosProduced++; c.dishNum = nosProduced; System.out.println("Kokk "+ c.ind+" lager tallerken num:" + c.dishNum ); // nosOnTable > 0 // Wake up a waiting waiter, // or all if nosProduced == NOS_TO_BE_MADE notifyAll(); if (nosProduced == NOS_TO_BE_MADE) { return false; } else{ return true; } } else { // nosProduced == NOS_TO_BE_MADE return false; } } // end putPlate public synchronized boolean getPlate(Waiter w) { while (nosOnTable == 0 && nosProduced < NOS_TO_BE_MADE ) { try { // The while test holds here // meaning that the table is empty and // there is more to serve System.out.println("Kelner " + w.ind + " VENTER paa aa servere en tallerken" ); wait(); } catch (InterruptedException e) { // Insert code to handle interrupt } } //one or both of the loop conditions are false if (nosOnTable > 0) { // 0 < nosOnTable <= TABLE_SIZE // Hence OK to decrease nosOnTable: nosOnTable--; System.out.println("Kelner "+w.ind+" serverer"+ " tallerken num:" + (nosProduced-nosOnTable) ); // nosOnTable < TABLE_SIZE // Must wake up a sleeping chef: notifyAll(); if (nosProduced == NOS_TO_BE_MADE && nosOnTable == 0) { return false; }else{ return true;} } else { // nosOnTable == 0 && // nosProduced == NOS_TO_BE_MADE return false;} } // end getPlate } // end class HeatingTable2 public class Restaurant2{ HeatingTable2 table; Restaurant2(String[] args) { table = new HeatingTable2(3,Integer.parseInt(args[0])); int numChefs = Integer.parseInt(args[1]), c = numChefs; int numWaiters = Integer.parseInt(args[2]), w = numWaiters; Thread [] t = new Thread[numChefs+numWaiters]; while (numWaiters-- > 0) ( t[numWaiters+1] = 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-thread is now 'alone¡®. Do other stuff .. } public static void main(String[] args) { Restaurant2 rest; if (args.length != 3) { System.out.println("use: >java Restaurant2 <#Chefs> <#Waiters>"); }else{ rest = new Restaurant2(args); } } // end main } // end Restaurant class Chef extends Thread { HeatingTable2 sharedTable; int ind; int dishNum; Chef(HeatingTable2 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 ferdig System.out.println("Kokk "+ind+" ferdig " ); } } // end Chef class Waiter extends Thread { HeatingTable2 sharedTable; int ind; Waiter(HeatingTable2 shared, int ind) { sharedTable = shared; this.ind = ind; } public void run() { try { while ((sharedTable.getPlate(this))){ // serve the plate sleep((long) (1000 * Math.random())); } } catch (InterruptedException e) {} System.out.println("Kelner " + ind+" ferdig"); // This Kelner has ferdig } } // end Waiter