// Kokk og servit?r // med Doug Leas concurrent-bibliotek // Med run()-metoden i subklasse av klassen Thread // Stein Gjessing -> mars 2025 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class RestaurantSubklassing { 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); kokk.start(); Servit?r servit?r = new Servit?r(bord,antallLage); 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(); //si fra til den som setter tallerkener p? bordet } finally { bordl?s.unlock(); } } } // slutt class FellesBord; class Kokk extends Thread { 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 extends Thread { 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 } }