Version: 5. félév

Bevásárlás a Fokeában járvány idején

A Fokea Lakberendezési Áruház a világjárvány idején is szeretné kiszolgálni vásárlóit. Azonban a járványügyi korlátozások miatt speciális intézkedéseket kellett bevezetnie: egyszerre csak n ember tartózkodhat az áruházban, továbbá az áruház teljes területén kötelező megtartani a másfél méter távolságot.

Készítsünk szimulátort, amely a tipikus Fokea vásárlók szokásait és a járványügyi szabályozások betartását is figyelembe veszi! A megoldás során fektess hangsúlyt a szálbiztos megoldásra (hiszen ezt fogjuk nézni elsősorban :))!

[+1 tipp: próbálj olvasható / Java-s konvenciókat betartó kódot készíteni, hiszen ez is része a ZH-jegynek!]

Feladatok#

Alapfeladat (4 pont)#

  • Biztonsági őr (SecuMan osztály):
    • egy szemaforral tartja számon, illetve szabályozza, hogy éppen hányan vannak benn
    • ezt megosztja a többi biztonsági őrrel (ezért konstruktorának paramétereként kapja)
    • a Fokea több bejárattal rendelkezik, ezért fontos, hogy mindegyik őr lássa, hogy épp hányan vannak benn
    • az enter és exit metódusokkal lehet megpróbálni átjutni egy biztonsági őrön, ami csak akkor sikerül, ha van még szabad kapacitás
  • Fokea osztály:
  • 2 biztonsági őrt hoz létre a jobb, illetve a bal kapuhoz
  • az aktuális szabályozások alapján beengedhető emberek maximális számát a konstruktorban kapja meg
  • az enter és exit metódusai a megfelelő kapunál álló őr azonos nevű metódusait hívják
  • a kapuk (jobb és bal) legyen egy enum típusba tartozók, melyet az enter/exit paraméterül kap
  • Person osztály:
    • egy szálat valósít meg
    • konstruáláskor megkapja a Fokea referenciáját
    • tevékenysége:
      • kezdetben véletlen ideig sétafikál (várakozik) (1-15 mp)
      • belép a Fokeába (választ egy kaput véletlenszerűen)
      • véletlen ideig nézelődik, vásárolgat (várakozik) (1-20 mp)
      • elhagyja a Fokeát
  • a main metódusban hozz létre egy Fokea objektumot, valamint embereket (lista), és indítsd is el a hozzájuk tartozó szálat
  • a maximálisan beengedhető létszámot állítsd kevesebbre, mint ahány vásárló (lézengő) lesz

Plüssnyúl (4 pont)#

  • a Person osztály ne legyen a szál leszármazottja, másképp oldd meg, hogy futtatható legyen egy szálon

  • gondoskodj róla, hogy a randomszám generálás szálbiztos legyen, úgy, hogy minden szál ugyanazt a randomszám generátort használja

  • a Fokea osztály rendelkezzen egy buyBunny művelettel, mely a következőképp működik:

    • egy Person objektumot kap paraméterül, aki megpróbál plüssnyulat venni
    • azonban a másfél méter betartása végett egyszerre csak 1 ember mehet a plüssnyúl tároló közelébe
    • gondoskodj róla, hogy egyszerre csak 1 szál hívhassa meg a metódust, de ügyelj rá, hogy ez ne tartsa fel a beléptetést/kilépést (azok a szálak ne blokkolódjanak azért, mert valaki plüssnyulat vesz) (Tipp: ne a Fokea-hoz tartozó mutex-et használd!)
    • fix darabszámú plüssnyúl áll rendelkezésre (50), ezt számon kell tartani a Fokea objektumban
    • egészítsd ki a Person tevékenységét egy plüssnyúl vásárlással + további nézelődéssel (a kezdeti nézelődés után, az áruház elhagyása előtt)
    • a Person objektum mielőtt elveszi plüssnyulat, véletlen ideig filóz, hogy melyik is legyen… (1-5mp), mindezt természetesen akkor teszi, amikor már bejutott a buyBunny metódusba (hogy a többiek még véletlenül se végezzenek időben…)
    • az elvétel után csökken a plüssnyulak darabszáma 1-el
    • ha valakinek már nem jutott plüssnyúl, sír és hazamegy: cryAndGoHome metódus, mely véletlen ideig vár (pár msp), majd kimegy a Fokeából

Családok (4 pont)#

  • mivel mindenki szeret családostul menni a Fokeába, legyen egy Family osztály
  • a Family osztály egy listában tartja számon a családtagokat, valamint a Fokea-ra is van referenciája
  • mivel a család tagjai nem képesek önálló létezésre, ezért egyszerre kell be-, illetve kilépniük
  • ehhez legyen enterFokea és exitFokea művelet
  • a Fokea/SecuMan osztályok nyújtsanak lehetőséget arra, hogy a családosok egyszerre tudjanak belépni/kilépni (mindent vagy semmit) (Tipp: kelleni fog egy-egy extra paraméter a műveleteknek)
  • a Person osztály kapja meg a családját referenciaként (ha van)
  • a családos ember nem megy be/ki egyedül, helyette a Family megfelelő műveletét használja, módosítsd a Person osztályt a megfelelő módon
  • FONTOS: ügyeljünk rá, hogy ha az egyik családtag már kezdeményezte a belépést/kilépést, a többiek már ne tudják a Fokea enter/exit műveleteit meghívni (ez elrontaná a számítást) [Tipp: boolean flag + mutex]
  • a main-ben hozz létre pár családot is; érdemes lehet egy start metódust írni a Family-be, ami elindítja a családtagok szálait

Raktáros (4 pont)#

  • mivel az egyes családtagok nem egyszerre végeznek, érd el, hogy a kilépés előtt várják be a többieket
  • ehhez érdemes lehet a java.util.concurrent.CountDownLatch osztályt használni
  • legyen szálat megvalósító raktáros (Storekeeper), aki a plüssnyulak feltöltéséért felel
    • működése nagyon egyszerű: ha elfogynak a plüssnyulak, visszatölti az eredeti darabszámot
    • ehhez persze figyelnie kell, mikor fogynak ki és lehetőleg addig a pontig várakoznia (blokkolni)
    • valamint tudnia kell épp hány darab plüssnyúl van a Fokeában (lehet pl belső osztály az egyszerűség végett)
    • mindehhez érdemes lehet vagy a java.util.concurrent.LinkedBlockingQueue, vagy Lock + Condition osztályok használata
    • ügyelj rá, hogy a fentieket szálbiztos módon valósítsd meg!
  • a Storekeeper álljon le, ha legalább 1 percig nem kap kérést feltöltésre
Last updated on