// Kokk og servitør // med Doug Leas concurrent-bibliotek // Stein Gjessing -> mars 2025 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Restaurant { public static void main(String[] args) { int antallPlass = Integer.parseInt(args[0]); int antallLage = Integer.parseInt(args[1]); FellesBord bord = new FellesBord(antallPlass); Kokk kokk = new Kokk(bord,antallLage); new Thread(kokk).start(); Servitør servitør = new Servitør(bord,antallLage); new Thread(servitør).start(); } } class FellesBord { // En monitor private Lock bordlås; private Condition ikkeTomtBord; private Condition ikkeFulltBord; private int antallPåBordet = 0; private final int BORD_KAPASITET; /* Invariant: 0 <= antallPåBordet <= BORD_KAPASITET */ public FellesBord (int ant) { BORD_KAPASITET = ant; bordlås = new ReentrantLock(); ikkeTomtBord = bordlås.newCondition(); ikkeFulltBord = bordlås.newCondition(); } public void settTallerken() throws InterruptedException { bordlås.lock(); try { while (antallPåBordet >= BORD_KAPASITET) { /* sa lenge det er BORD_KAPASITET tallerkner pa bordet er det ikke lov a sette pa flere. */ ikkeFulltBord.await(); } // Na er antallPåBordet < BORD_KAPASITET. // Bordet er ikke fullt. antallPåBordet++; // Invarianten holder + antallPåBordet > 0 System.out.println("Antall på bordet: " + antallPåBordet); ikkeTomtBord.signal(); // Si fra til den som tar tallerkener } finally { bordlås.unlock(); } } public void hentTallerken() throws InterruptedException { bordlås.lock(); try { while (antallPåBordet == 0) { /* Så lenge det ikke er noen tallerkener på bordet er det ikke lov å ta en */ ikkeTomtBord.await(); } // Nå er antallPåBordet > 0 // Nå kan vi ta en tallerken antallPåBordet --; // Invarianten holder + antallPåBordet < BORD_KAPASITET ikkeFulltBord.signal(); //i fra til den som setter tallerkener pa bordet } finally { bordlås.unlock(); } } } // slutt class FellesBord; class Kokk implements Runnable { private FellesBord bord; private final int ANTALL; private int laget = 0; Kokk(FellesBord bord, int ant) { this.bord = bord; ANTALL = ant; } @Override public void run() { try { while(ANTALL != laget) { laget ++; System.out.println("Kokken lager tallerken nr: " + laget); bord.settTallerken(); Thread.sleep((long) (500 * Math.random())); } } catch (InterruptedException e) {System.out.println("Uventet stopp 1");} // Kokken er ferdig } } class Servitør implements Runnable { private FellesBord bord; private final int ANTALL; private int servert = 0; Servitør(FellesBord bord, int ant) { this.bord = bord; ANTALL = ant; } @Override public void run() { try { while (ANTALL != servert) { bord.hentTallerken(); servert++; System.out.println("Kelner serverer nr:" + servert); Thread.sleep((long) (1000 * Math.random())); } } catch (InterruptedException e) { System.out.println("Uventet stopp 2");} // servitøren er ferdig } }