12. praktikum. Harjutused
Ülesanne 1
Seikluspargis koosneb rada rippsildadest. Selles ülesandes on raja läbimist simuleeritud.
public class Rippsild { private char sillaTähis; private int läbimiseAeg; public Rippsild(char sillaTähis, int läbimiseAeg) { this.läbimiseAeg = läbimiseAeg; this.sillaTähis = sillaTähis; } public void ületa(Seikleja seikleja) throws InterruptedException { // public synchronized void ületa(Seikleja seikleja) throws InterruptedException { System.out.println(seikleja.getNimi() + " astus sillale " + sillaTähis + " " + ((System.currentTimeMillis() - seikleja.getAlgusAeg()) / 1000)); Thread.sleep(1000 * läbimiseAeg); System.out.println(seikleja.getNimi() + " lahkus sillalt " + sillaTähis + " " + (System.currentTimeMillis() - seikleja.getAlgusAeg()) / 1000); } } public class Seikleja implements Runnable { private String nimi; private boolean kasAlgusest; private Rippsild[] rippsillad; private long algusAeg; public Seikleja(String nimi, Rippsild[] rippsillad, boolean kasAlgusest) { this.nimi = nimi; this.rippsillad = rippsillad; this.kasAlgusest = kasAlgusest; } public String getNimi() { return nimi; } public long getAlgusAeg() { return algusAeg; } public void run() { this.algusAeg = System.currentTimeMillis(); try { if (kasAlgusest) { for(int i = 0; i < rippsillad.length; i++) rippsillad[i].ületa(this); } else { for(int i = rippsillad.length - 1; i>= 0; i--) rippsillad[i].ületa(this); } } catch (InterruptedException e) { throw new RuntimeException(e); } } }
Peaklass on järgmine.
public class Seikluspark { public static void main(String[] args) { Rippsild[] sillad = {new Rippsild('A', 10), new Rippsild('B', 20)}; Seikleja seikleja1 = new Seikleja("Rasmus", sillad, true); Seikleja seikleja2 = new Seikleja("Grete", sillad, false); Thread t1 = new Thread(seikleja1); Thread t2 = new Thread(seikleja2); t1.start(); t2.start(); } }
Ülesanne 1.1
Mis ilmub ekraanile. Miks?
Ülesanne 1.2
Mis ilmuks ekraanile, kui meetod ületa
ees oleks lisaks võtmesõna synchronized? Miks?
Ülesanne 2
Taheti koostada programm, mis simuleeriks laste mängimist mänguasjadega mängutoas. Programm pidi tagama järgmiste tingimuste kehtimise:
- Mängutoas saab korraga mitu last mängida.
- Laps saab korraga võtta mänguasjariiulist ainult ühe mänguasja.
- Konkreetse mänguasjaga saab korraga mängida vaid üks laps.
- Laps eelistab alati mänguasja, millel on kõige pikem nimi.
- Pärast mänguasjaga mängimist paneb laps selle riiulile tagasi.
Paraku see päriselt ei õnnestunud. Märkida järgnevast loetelust, mis põhjus(t)el see programm korrektselt ei tööta. Selgitada iga vastuse variandi korral, kuivõrd see võib olla põhjuseks.
- Laps ei saa kasutada mängutuba, sest tema lõim võib enne tööd alustada, kui
Mängutuba
on loodud. - Meetodit
run
klassistLaps
ei ole üldse välja kutsutud. - Meetod
leiaMänguasi
klassisMängutuba
peab olema sünkroniseeritud. - Meetod
tagastaMänguasi
klassisMängutuba
peab olema sünkroniseeritud. - Meetod
run
klassisLaps
peab olema sünkroniseeritud. - Klassi
Laps
isenditele ei saa üldse konstruktori parameetreid anda, sestLaps
realiseerib liidestRunnable
. - Teine laps ei saa kunagi mängimist alustada, sest esimese lapse tegevus on lõpmatus tsüklis.
- Isend
laps1
on loodud valesti, talle tüübiks on pandudRunnable
, seda ei tohi teha. - Isend
laps2
on loodud valesti, talle tüübiks on pandudLaps
, aga peab olema kindlastiRunnable
.
public class Laps implements Runnable { private Mängutuba mängutuba; private String nimi; public Laps(Mängutuba mängutuba, String nimi) { this.mängutuba = mängutuba; this.nimi = nimi; } public void run() { while (true) { String mänguasi = mängutuba.leiaMänguasi(); System.out.println(nimi + " mängib mänguasjaga " + mänguasi); mängutuba.tagastaMänguasi(mänguasi); } } } public class Mängutuba { private String[] riiul; public Mängutuba(String[] mänguasjad) { this.riiul = mänguasjad; } public String leiaMänguasi() { int parim = -1; for (int i = 0; i < riiul.length; i++) { if (riiul[i] != null && (parim == -1 || riiul[i].length() > riiul[parim].length())) { parim = i; } } String valik = riiul[parim]; riiul[parim] = null; return valik; } public void tagastaMänguasi(String mänguasi) { for (int i = 0; i < riiul.length; i++) { if (riiul[i] == null) { riiul[i] = mänguasi; break; } } } public static void main(String[] args) { Mängutuba mängutuba = new Mängutuba(new String[]{"rong", "puzzle", "nukk"}); Runnable laps1 = new Laps(mängutuba, "Volli"); Laps laps2 = new Laps(mängutuba, "Martin"); Thread t1 = new Thread(laps1); Thread t2 = new Thread(laps2); t1.start(); t2.start(); } }