import java.util.ArrayList; import java.util.Random; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* Lag klassen Barista, som er en tr?d. Alle har et array med ulike kaffedrikker private final String[] drikker = {"Americano", "Caf¨¦ au lait", "Caff¨¨ latte", "Caff¨¨ mocca", "Espresso", "Cortado"}; I tillegg tar Baristaen inn et bord (som du skal lage i oppgave E) vedkommende kan servere kaffen p?, og en id. */ class Barista implements Runnable{ private Bord bord; private int id; private final String[] drikker = {"Americano", "Caf¨¦ au lait", "Caff¨¨ latte", "Caff¨¨ mocca", "Espresso", "Cortado"}; public Barista(Bord b, int id){ bord = b; this.id = id; } @Override public void run(){ /* Implement¨¦r metoden run i Barista. Hver barista lager ti kaffe, og disse drikkene skal velges tilfeldig fra en liste med drikker (Tips: bruk java.util.Random for ? f? et tall mellom 0 og lengden til drikker). Baristaen skal skrive ut sin id og hvilken drikke som blir laget f?r vedkommende serverer kaffen p? bordet. N?r ti kaffe er servert, skal baristaen melde i fra at vedkommende er ferdig (inkludert id-en til baristaen). */ Random random = new Random(); for (int i = 0; i < 10; i++){ int indeks = random.nextInt(drikker.length); String drikke = drikker[indeks]; bord.serverKaffe(drikke); System.out.println("Barista "+ id + " sererverer en " + drikke); } System.out.println("Barista " +id + " er ferdig. "); } } /* Lag klassen Kaffedrikker, som er en tr?d. Kaffedrikker tar inn et bord vedkommende kan hente kaffe fra, og en id. Implementer metode run i Kaffedrikker. Denne skal ha en teller som teller antall kaffer som kaffedrikkeren f?r drukket. S? lenge kaffedrikeren f?r beskjed om at det ikke er tomt skal vedkommende printe sin id og hvilken kaffe som ble drukket. N?r det ikke er flere kaffer for kaffedrikkeren ? drikke skal vedkommende printe sin id og hvor mange kaffekopper som ble drukket. */ class Kaffedrikker implements Runnable{ private Bord bord; private int id; public Kaffedrikker(Bord b, int i){ bord = b; id = i; } @Override public void run(){ // N?r vi har implementert Bord og bruker await() ser vi at vi trenger en try catch, fordi await() kaster en InterupptedException som vi m? h?ndtere her. int antKaffe = 0; try{ String kaffe; while ((kaffe = bord.hentKaffe()) != null){ System.out.println("Kaffedrikker " + id + " drikker en " + kaffe); antKaffe++; } } catch(InterruptedException e){ Thread.currentThread().interrupt(); System.out.println("Kaffedrikker " + id + "ble avbrutt."); } finally{ System.out.println("Kaffedrikker " + id + " har drukket "+ antKaffe + " kopper kaffe."); } } } /* Lag klassen Bord. Lag en metode som serverer kaffe (legger de til i bordet). Husk at det kan v?re uendelig mange kaffer p? bordet om gangen. Lag ogs? en metode hentKaffe som henter en kaffe fra bordet s? lenge det er en kaffe der, og signaliserer til Kaffedrikker n?r det er tomt. Lag klassen Hovedprogram som lager et bord, to baristaer og ti kaffedrikkere. Test gjerne med ulike verdier for ? se hvordan programmet oppf?rer seg. */ class Bord{ private ArrayList kopper = new ArrayList<>(); // fordi vi ikke vet hvor mange kopper som skal v?re p? bordet, og bordet blir aldri fullt. private Lock l?s = new ReentrantLock(); private Condition ikkeTomt = l?s.newCondition(); private int totaltAntallKopper; // antall kopper vi totalt kommer til ? f? public Bord(int ant){ totaltAntallKopper = ant; } public void serverKaffe(String kopp){ l?s.lock(); try{ kopper.add(kopp); totaltAntallKopper--; ikkeTomt.signalAll(); }finally{ l?s.unlock(); } } public String hentKaffe() throws InterruptedException{ // .await() kaster interrupptedException og vi m? h?ndtere det. l?s.lock(); try{ while(kopper.isEmpty() && totaltAntallKopper > 0){ // Fordi vi ikke vil at kaffedrikker-tr?dene avslutter mens det fortsatt er baristaer som kommer til ? servere kaffe. ikkeTomt.await(); } if (!kopper.isEmpty()){ return kopper.remove(0); } return null; } finally{ l?s.unlock(); } } }