Jaana Diakite Projekti 1 JAVA-Monitorit 1(13) Rinnakkaisohjelmointi Anu Uusitalo

Samankaltaiset tiedostot
Rinnakkaisohjelmointi, Syksy 2006

Liite 1. Projektin tulokset (Semaforit Javassa) Jukka Hyvärinen Aleksanteri Aaltonen

Monitorit. Monitori Synkronointimenetelmiä Esimerkkejä. Andrews , Stallings 5.5

Monitorit. Tavoite. Monitori Synkronointimenetelmiä Esimerkkejä. Andrews , Stallings 5.5. Minimoi virhemahdollisuuksia

Projekti 1 Säikeet ja kriittisen vaiheen kontrollointi javalla

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

Monitorit -projekti Rinnakkaisohjelmointi

Javan perusteita. Janne Käki

Luento 6. T Ohjelmoinnin jatkokurssi T1 & T Ohjelmoinnin jatkokurssi L1. Luennoitsija: Otto Seppälä

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

10 Lock Lock-lause

Olio-ohjelmointi Javalla

Javan semaforit. Joel Rybicki, Aleksi Nur mi, Jara Uitto. Helsingin yliopisto

Tavoite. Monitorit. Monitori Hoare Monitori. Minimoi virhemahdollisuuksia. Monitori Synkronointimenetelmiä Esimerkkejä

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

Ohjelmointi 2 / 2010 Välikoe / 26.3

Rajapinta (interface)

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

T Henkilökohtainen harjoitus: FASTAXON

11. Javan toistorakenteet 11.1

Mikä yhteyssuhde on?

KOHDELUOKAN MÄÄRITTELY

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Taulukot. Jukka Harju, Jukka Juslin

15. Ohjelmoinnin tekniikkaa 15.1

9. Periytyminen Javassa 9.1

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

15. Ohjelmoinnin tekniikkaa 15.1

Pino S on abstrakti tietotyyppi, jolla on ainakin perusmetodit:

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 22. Taulukot. Yleistä. Yleistä

812315A Ohjelmiston rakentaminen. Asynkronisuus

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2

Ohjelmointi 2 / 2008 Välikoe / Pöytätestaa seuraava ohjelma.

Sisällys. 11. Javan toistorakenteet. Laskurimuuttujat. Yleistä

4. Luokan testaus ja käyttö olion kautta 4.1

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

Sisällys. 6. Metodit. Oliot viestivät metodeja kutsuen. Oliot viestivät metodeja kutsuen

RINNAKKAINEN OHJELMOINTI A,

7. Oliot ja viitteet 7.1

14. Poikkeukset 14.1

Käyttöjärjestelmät: poissulkeminen ja synkronointi

Rinnakkaisuus. parallel tietokoneissa rinnakkaisia laskentayksiköitä concurrent asioita tapahtuu yhtaikaa. TTY Ohjelmistotekniikka

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

14. Poikkeukset 14.1

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Vertailulauseet. Ehtolausekkeet. Vertailulauseet. Vertailulauseet. if-lauseke. if-lauseke. Javan perusteet 2004

Listarakenne (ArrayList-luokka)

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

12. Javan toistorakenteet 12.1

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Oliot viestivät metodeja kutsuen

1 Tehtävän kuvaus ja analysointi

Johdatus Java 1.5:n semaforeihin

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

Luokan muodostimet (Constructors)

Java kahdessa tunnissa. Jyry Suvilehto

16. Javan omat luokat 16.1

YHTEYSSUHDE (assosiation)

Metodien tekeminen Javalla

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Semaforit Javassa. Mari Kononow, Eveliina Mattila, Sindi Poikolainen HELSINGIN YLIOPISTO

Java-API, rajapinnat, poikkeukset, UML,...

12. Javan toistorakenteet 12.1

poissulkeminen ohjelmoijan vastuulla P():t ja V():t siellä, täällä ja tuolla - meniköhän oikein? Yksityiskohtia pois ohjelmoijalta kääntäjälle

Monitorit. Monitori Synkronointimenetelmiä Esimerkkejä

Luokan sisällä on lista

Tavoite. Monitorit. Semafori perusmekanismi synkronointiin. Hyötyjä:

9. Periytyminen Javassa 9.1

OSA I: Yhteisten muuttujien käyttö Prosessit samassa koneessa. Sisältöä. Poissulkeminen. Halutut ominaisuudet 2-1. Rinnakkaiset, atomiset operaatiot

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä

Ongelmakenttä. Yhteenvetoa. Mekanismit. Ratkottava. Lukkomuuttujat, Spin Locks. Lukkomuuttujat. Rinnakkaisohjelmistot 2004 / Auvo Häkkinen 9-1

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

2. Olio-ohjelmoinista lyhyesti 2.1

A TIETORAKENTEET JA ALGORITMIT

4. Olio-ohjelmoinista lyhyesti 4.1

1. Mitä tehdään ensiksi?

ITKP102 Ohjelmointi 1 (6 op)

Oppimistavoitteet kurssilla Rinnakkaisohjelmointi

TIES542 kevät 2009 Yhteismuistisamanaikaisuus

Taulukot, silmukat ja muut joka koodin pikku veijarit

20. Javan omat luokat 20.1

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang

Metodit Arvotyyppi. Metodit Arvotyyppi. Metodit Parametrit. Metodit Parametrit. Metodit Kuormittaminen. Metodit Kuormittaminen. Javan perusteet

18. Abstraktit tietotyypit 18.1

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

Tietokannat II -kurssin harjoitustyö

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

1. Omat operaatiot 1.1

Transkriptio:

Jaana Diakite Projekti 1 JAVA-Monitorit 1(13) JAVA MONITORIT Monitorien käyttötarkoitus ja sovellusalue Monitorit ovat Java ohjelmointikielen sisäänrakennettu mekanismi säikeiden rinnakkaisuuden hallintaan. C.A.R. Hoare esitti ensimmäistä kertaa monitorin käsitteen vuonna 1974. Rinnakkaisuuden hallinta on monimutkaista ja virhealtista: monitorit tarjoavat tähän semaforeja luotettavamman ja helppokäyttöisemmän rakenteellisen työkalun. Java monitorien perusidea Javassa monitorina voi toimia mikä tahansa olio. Monitoriolion avulla kriittiset, suojaamista tarvitsevat toiminnot voidaan kapseloida olion sisään niin, että monitori kontrolloi näihin toimintoihin pääsyä. Monitorilla on aina lukko (lock) ja odotusjoukko (wait set). Monitorin kontrolloimat metodit ja koodilohkot varustetaan avainsanalla synchronized. Monitorien käyttöön liittyvät myös Object luokan metodit wait(), notify() ja notifyall(). Kun säie haluaa suorittaa suojattua toimintaa, sen pitää saada haltuunsa monitorin lukko, jonka voi omistaa vain yksi säie kerrallaan. Lukon avulla voidaan siis suojata kriittiset toiminnot rinnakkaisesti suoritettavilta säikeiltä. Ne säikeet jotka odottavat pääsyä suojattuun osioon, sijoitetaan monitorin odotusjoukkoon. Odotusjoukossa olevat säikeet odottavat lukon vapautumista ja oikeutta suorittaa monitorin valvomia toimintoja. Kun lukkoa hallussaan pitävä säie luopuu siitä, se antaa ilmoituksen (notify) lukon vapautumisesta odotusjoukon säikeille. Ilmoituksen saanut säie odottaa, kunnes ilmoittaja poistuu monitorista ja alkaa tämän jälkeen suorittaa toimintojaan. Ilmoittaminen voidaan kohdistaa yhteen satunnaisesti valittuun odotusjoukon säikeeseen (notify) tai kaikkiin odottaviin säikeisiin (notifyall). Javassa on myös luokkakohtaisia static-metodeita, joihin ei liity olioita. Luokkametodit voidaan myös määritellä synkronoiduiksi luokkakohtaisilla lukoilla. Luokkakohtainen ja

Jaana Diakite Projekti 1 JAVA-Monitorit 2(13) oliokohtainen lukko ovat toisistaan riippumattomia, joten nämä voivat olla suorituksessa yhtä aikaa. Monitorin ja Java-monitorin yhteneväisyydet ja eroavaisuudet Java monitorien perusidea on sama kuin perusmonitorienkin, mutta Javassa ei ole erillistä monitor-luokkaa vaan kuten edellä mainittiin jokainen olio voi toimia monitorina. Java-monitori toteuttaa monitoreille asetettua vaatimusta, että kääntäjän avulla tarkistetaan koodin oikeellisuutta ja näin vähentää virheiden määrää. Se täyttää kapselointi odotukset eli palvelun kutsujan ei tarvitse tietää miten yksittäinen palvelu on toteutettu eikä monitorin tekijän tarvitse tietää kuka, missä, miten ja milloin sen tuottamia palveluita kutsuu. Java-monitorit eivät myöskään salli viittauksia ulkopuolisiin muuttujiin, eikä samanaikaista saman objektin palveluiden kutsua (automaattinen poissulkeminen). Java-monitorin suoritukseen päässyt säie käyttää Ilmoita ja Jatka - signalointisemantiikkaa. Toinen signalointisemantiikka vaihtoehto Ilmoita ja Keskeytä ei ole mahdollinen Javassa. Toisaalta taas Java-monitorissa on vaihtoehtoina ilmoittaa kaikille (notifyall()) tai vain yhdelle satunnaisesti valitulle (Notify()) säikeelle monitorin vapautumisesta. Kaikille säikeille ilmoittaminen (NotifyAll()) johtaa kaikkien säikeiden vapautumiseen ja Java-monitorin sisälle pääsyehtojen uudelleen tarkistamiseen kaikkien säikeiden kohdalla. Perusmonitoreissa yleensä vain yksi prosessi odottaa ilmoitusta sisään pääsystä, kun taas kaikki Javan käynnistämä säikeet odottavat whilen kaltaisessa luupissa. Tämä johtaa yleensä säikeiden lukumäärän kasvaessa tehottomuuteen ja raskauteen. Javassa on myös mahdollista antaa säikeille kolme erilaista prioriteettia: min, max tai normaali. Perusmonitoreissa on ehtomuuttujia käyttäen mahdollista keskeyttää tietyn palvelun toiminto odottamaan tietyn toiminnan valmistumista ja vapauttaa näin monitorin muut palvelut muiden käyttöön. Java-monitorit eivät toteuta täysin perusmonitorien IRRominaisuutta (immediate resumption requirement), niillä on vain yksi odotusjono monitorin ulkopuolella yhtä objektia kohden (E = W < S). Lisäksi tämä odotusjono ei ole

Jaana Diakite Projekti 1 JAVA-Monitorit 3(13) perusmonitorien tapaan FIFO-jono, niin se ei myöskään takaa sitä, että ensimmäisenä luotu säie pääse suoritukseen myös ensimmäisenä. Tämä tarkoittaa, että nälkiintyminen on täysin mahdollista Java-monitorissa. Monitorien käyttöesimerkit Aterioivat filosofit Edsger Dijkstra esitti vuonna 1965 tietojenkäsittelyn rinnakkaisuuteen liittyvän aterioivien filosofien ongelman. Dijkstran esittämässä ongelmassa viisi filosofia istuu pyöreän pöydän ympärillä. Jokaisella filosofilla on edessään lautasellinen spagettia ja yksi haarukka lautasen vasemmalla puolella. Syödäkseen jokainen filosofi tarvitsee kuitenkin kaksi haarukkaa, sekä oman haarukkansa, että oikealla puolella istuvan filosofin haarukan. Filosofien elämä koostuu ajattelemisesta ja syömisestä. Filosofin tullessa nälkäiseksi hän yrittää saada itselleen lautasen vasemmalla ja oikealla puolella olevat haarukat. Mikäli filosofi onnistuu saamaan molemmat haarukat, syö hän jonkin aikaa kunnes tulee kylläiseksi ja laskee sitten haarukat takaisin pöydälle ja jatkaa miettimistä. Tavoitteena on luoda filosofeille toimintaohje, jonka avulla kukin filosofi pääsee syömään eikä ohjelma pääse lukkiutumaan. Seuraavassa on esitetty ohjelman toteutus Java monitorien avulla: class DiningMonitor //ohjelman attribuutit //filosofien lukumäärän kertova attribuutti private final int numberofphils; // olio-taulukko, jonka jokainen olio toimii //yhden filosofin monitorina private Object[] monitorbuffer;

Jaana Diakite Projekti 1 JAVA-Monitorit 4(13) //haarukoiden järjestysnumerot sisältävä //taulukko private int[] forkbuffer; // Boolean muuttuja, jonka avulla testataan //filosofien nälkiintymistilanne private boolean checkstarvation = true; // filosofien nälkiintymistilannetta ylläpitävä //taulukko private boolean[] starvationbuffer = null; public DiningMonitor(int numphils) throws IllegalArgumentException int i; // Asetetaan parametrina saatu //filosofien määrä numberofphils //muuttujan arvoksi ja luodaan uudet //taulukot monitoreja ja haarukoita //varten numberofphils = numphils; monitorbuffer = new Object[numberOfPhils]; forkbuffer = new int[numberofphils]; // Käydään läpi yllä luodut uudet //taulukot ja.. for(i=0;i < numberofphils;i++) //asetetaan jokaisen haarukan //alkuarvoksi 1 (käytettävissä) forkbuffer[i] = 1; monitorbuffer[i] = new Object(); //Tarkistetaan nälkiintymistilanne if(checkstarvation) //uusi taulu nälkiintymistilanteen //ylläpitämiseksi starvationbuffer = new boolean[numberofphils]; //Asetetaan aluksi jokainen //filosofi kylläiseksi for(i=0;i < numberofphils;i++) starvationbuffer[i] = false;

Jaana Diakite Projekti 1 JAVA-Monitorit 5(13) // pyydetään haarukoita public void takeforks(int i) //monitoroitu olio (ohjelmalohko) synchronized(monitorbuffer[i]) try // pyydetään lupaa ottaa //haarukat testavailable() -//metodilta while(!testavailable(i) ) monitorbuffer[i].wait(); catch(interruptedexception ie) ; // vapautetaan käytetyt haarukat muiden //ruokailijoiden käytettäviksi public synchronized void putforks(int i) forkbuffer[i]=1; forkbuffer[(i+1)%numberofphils]=1; indicate((i+numberofphils-1)%numberofphils); indicate((i+1)%numberofphils); // tarkistetaan, onko tarvittavat haarukat //käytettävissä //monitoroitu metodi.. private synchronized boolean testavailable(int i) boolean cond,starvecond = true; // testataan, onko haarukat vapaina cond = (forkbuffer[i]==1) && (forkbuffer[(i+1)%numberofphils]==1); if(checkstarvation)

Jaana Diakite Projekti 1 JAVA-Monitorit 6(13) // Tarkistetaan, onko //naapurifilosofit nälkiintymässä starvecond =!starvationbuffer[(i+numberofphils-1) %numberofphils] &&!starvationbuffer[(i+1)%numberofphils]; if(!cond) // asetetaan haarukoita //pyytänyt filosofi //nälkiintyväksi if(starvecond) starvationbuffer[i] = true; if(cond && starvecond) // merkitään haarukat varatuiksi.. forkbuffer[i]=0; forkbuffer[(i+1)%numberofphils]=0; //ja nollataan nälkiintymistilanne if(checkstarvation) starvationbuffer[i] = false; return(cond && starvecond); // Vapautetaan haarukat muiden käytettäviksi private void indicate(int i) //monitoroitu olio synchronized(monitorbuffer[i]) //vapautetaan lukko odotusjoukon //säikeille monitorbuffer[i].notify();

Jaana Diakite Projekti 1 JAVA-Monitorit 7(13) Ohjelmassa jokaiselle filosofille annetaan aluksi järjestysnumero (metodi DiningMonitor). Järjestysnumeron perusteella kontrollioliot tietävät filosofin paikan pöydässä (monitorbuffer, forkbuffer, starvationbuffer). Annettujen järjestysnumeroiden avulla luodaan uudet taulukot filosofien monitorien, haarukoiden ja nälkiintymistilanteen hallintaa varten. Filosofien määrä määrittelee taulukkojen koot. Jokaiseen taulukkoon lisätään kullekin filosofille oma alkio. Kunkin taulukon alkio alustetaan alussa ruokailuun pyrkimisen kannalta suotuisaan tilaan eli filosofit asetetaan kylläisiksi, kaikki haarukat saataville ja monitorien valvomat toiminnot suoritettaviksi. Filosofin tullessa nälkäiseksi kutsuu ohjelma DiningMonitor -luokan metodia takeforks(), jolle välitetään parametrina nälkäisen filosofin järjestysnumero. TakeForks() metodin monitorina toimii yksi oliotaulukon monitorbuffer alkio. TakeForks() metodi välittää ruokailemaan pyrkivän filosofin järjestysnumeron edelleen testavailable() metodille, joka tarkistaa aluksi filosofin järjestysnumeron perusteella, onko filosofin molemmin puolin löytyvät haarukat vapaana käytettäviksi. Seuraavaksi metodi tarkistaa, ettei filosofin kumpikaan naapuri ole nälkiintymässä. Jos haarukat ovat käytettävissä eivätkä naapurit ole nälkiintymässä, merkitsee metodi haarukat varatuiksi, nollaa filosofin nälkiintymistilanteen ja antaa takeforks() -metodille luvan päästää filosofin syömään välittämällä tälle arvon true. Filosofin tavoitellessa haarukoita, voi hän ottaa haarukan vain, jos hänen kumpikaan naapuri ei ole nälkiintymässä. Jos haarukat eivät ole käytettävissä eikä filosofin naapurit ole nälkiintymässä, asettaa metodi haarukoita pyytäneen filosofin nälkiintyväksi ja välittää takeforks() metodille vastaukseksi false, jolloin säie siirtyy odotustilaan ja monitorbuffer[i] -oliotaulukon odotusjoukkoon. Niin ikään, jos filosofin pyytämät haarukat eivät ole saatavilla ja filosofin naapureista

Jaana Diakite Projekti 1 JAVA-Monitorit 8(13) toinen tai molemmat ovat nälkiintymässä, palautetaan takeforks() metodille false eikä ruokailemaan pyrkinyttä filosofia aseteta nälkiintyväksi. Näin jokainen filosofi pääsee jossakin vaiheessa syömään, eikä yksikään pääse nälkiintymään. Koska metodi takeforks() on synkronoitu vain oliotaulukon monitorbuffer alkion suhteen, voi metodia suorittaa useampi säie yhtä aikaa. Tämän vuoksi metodin testavailable() on oltava synkronoitu koko DiningMonitor olion suhteen, jotta haarukkataulukkoa ei päästäisi muuttamaan useammasta säikeestä yhtä aikaa. Filosofin päästyä syömään kutsuu ohjelma seuraavaksi putforks() metodia, joka vapauttaa haarukat muiden filosofien käytettäviksi. PutForks() metodille välitetään niin ikään ruokailleen filosofin järjestysnumero, jonka perusteella metodi merkitsee ruokailleen filosofin haarukat vapaiksi asettamalle niiden arvoksi 1. Metodi kutsuu vielä säikeen lukon vapauttamisesta viestittävää metodia indicate(), joka ilmoittaa haarukoiden vapautumisesta niitä odottaville filosofeille (odotusjoukon säikeille). Koska jokaisella filosofilla on oma monitori, jonka odotusjoukossa se on (monitorbuffer[i]), voidaan haarukoiden vapautumisesta viestittää suoraan niitä filosofeja, joita tämä saattaa koskea. Nukkuva parturi Nukkuva parturi ongelma on niin ikään Edsger Dijkstran keksimä rinnakkaisuudenhallintaa kuvaava ongelma. Parturiliikkeessä on yksi parturi, yksi parturin tuoli ja joukko odotustuoleja parturin asiakkaita varten. Kun parturilla ei ole yhtään asiakasta, parturi istuu tuolissansa ja nukkuu. Kun liikkeeseen saapuu uusi asiakas, tämä joko herättää nukkuvan parturin, tai jos parturi leikkaa parhaillaan toisen asiakkaan hiuksia, istuutuu odotusaulan vapaalle tuolille odottamaan omaa vuoroaan. Mikäli kaikki odotusaulan tuolit

Jaana Diakite Projekti 1 JAVA-Monitorit 9(13) ovat varattuja, poistuu viimeksi liikkeeseen tullut asiakas paikalta saamatta palvelua. Seuraavassa on esitetty nukkuva parturi ongelma Java monitorien avulla: //Asiakkaiden toimintaa ohjaava proseduuri procedure customer_itinerary boolean succeeded; succeeded = Customers.TryHaircut(); if (!succeeded) no_haircut(); //Parturin toimintaa ohjaava proseduri procedure barber_itinerary while (1) Barber.NextCustomer(); CutHair(); Barber.CustomerDone(); //Customer-luokka Class Customers //asetetaan parturintuoli vapaaksi ja //vapaita odotustuoleja viisi kappaletta boolean barber_chair_free = TRUE; int free_waiting_chairs = 5; //monitoroitu ohjelmalohko synchronized boolean TryHaircut //onko yhtään odotustuolia vapaana if (free_waiting_chairs == 0) return FALSE; // Tarkistetaan, onko parturilla asiakas tai // asiakkaita odottamassa odotustuoleilla, jos //parturilla on asiakas ja odotustuoleilla on //vielä tilaa istutaan odotustuolille if ((barber_chair_free == FALSE) (free_waiting_chairs < 5)) //vähennetään vapaiden odotustuolien määrää

Jaana Diakite Projekti 1 JAVA-Monitorit 10(13) free_waiting_chairs--; //odotetaan omaa vuoroa (asetetaan säie //odottavaan tilaan..) wait(); //oman vuoron tultua vapautetaan odotustuoli free_waiting_chairs++; //varataan parturin tuoli barber_chair_free = FALSE; //ilmoitetaan parturi-luokan metodilla DoNotify //parturille, että tuoliin on istuutunut asiakas barber.donotify(); //kutsutaan Barber-luokan metodia WaitForCutToFinish barber.waitforcuttofinish(); //asetetaan parturituoli vapaaksi barber_chair_free = TRUE; // barber.donotify(); //ilmoitetaan parturituolinvapautumisesta //jonossa oleville odotusjoukonsäikeille notify() //hiustenleikkaus suoritettu return TRUE; //monitorilla suojattu metodi synchronized boolean CheckChairFree() return barber_chair_free; //Barber-luokka Class Barber //Monitoriksi määritetty metodi synchronized void NextCustomer //Tarkistetaan customer-luokan metodilta, //istuuko parturintuolissa asiakas if (Customers.CheckChairFree() == TRUE) // jos tuoli on vapaana, odotetaan, että joku //istuutuu parturin tuoliin wait();

Jaana Diakite Projekti 1 JAVA-Monitorit 11(13) //monitoriksi määritetty metodi synchronized void CustomerDone() //ilmoitetaan, että hiustenleikkaus on valmis notify(); wait(); //monitoriksi määritetty metodi synchronized void DoNotify() notify(); //monitoriksi määritetty metodi synchronized void WaitForCutToFinish () //odotetaan, että hiustenleikkaus saadaan valmiiksi wait(); Parturin saapuessa töihin kutsuu parturin toimintaa ohjaava proseduuri barber_itinerary Barber luokan metodia NextCustomer, joka tarkistaa, istuuko parturintuolissa jo asiakas odottamassa palvelua. Jos tuoli on tyhjä, asetetaan metodia suorittava säie odottavaan tilaan wait()-komennolla. Näin säie luovuttaa monitorin hallinnan pois ja jää odottamaan säikeen etenemisen mahdollistavaa notify-viestiä joltakin toiselta säikeeltä. Eli parturi ryhtyy nukkumaan ja odottamaan seuraavaa palveltavaa asiakasta. Asiakkaan saapuessa parturiin kutsuu asiakkaiden toimintaa ohjaava proseduuri customer_itinerary Customer-luokan metodia TryHaircut. Metodi tarkistaa aluksi, onko parturin odotusaulan kaikki tuolit varattuja. Jos kaikki odotustuolit ovat varattuja, palauttaa ohjelma metodia kutsuneelle proseduurille paluuarvona FALSE. Asiakas ei onnistunut saamaan palvelua. Jos odotustuoleilla on vielä tilaa, tarkistaa ohjelma seuraavaksi, onko parturi varattuna tai odottavia asiakkaita odotusaulan tuoleilla. Parturin tai osan odotustuoleista ollessa varattuna, varaa ohjelma asiakkaalle yhden odotusaulan tuoleista vähentämällä tuolitilannetta ylläpitävän attribuutin free_waiting_chairs arvoa yhdellä.

Jaana Diakite Projekti 1 JAVA-Monitorit 12(13) Vastaavasti jos odotusaula on tyhjä ja parturin tuoli on vapaa, merkitsee ohjelma parturin tuolin varatuksi asettamalla attribuutin barber_chair_free arvoksi false. Asiakas istuutuu parturin tuoliin. Tämän jälkeen ohjelma herättää nukkuvan parturin kutsumalla Barber luokan metodia DoNotify, joka antaa Notify-viestin Barber-luokan NextCustomer metodissa odottavalle säikeelle. Säie pääsee nyt jatkamaan suoritusta. Parturi ryhtyy näin leikkaamaan asiakkaan hiuksia. Seuraavaksi Customer proseduuri suorittaa Barber-luokan metodin WaitForCutToFinish eli asiakas odottaa, että parturi saa hiukset leikattua. Metodin säie asetetaan odotustilaan. Parturi proseduuri kutsuu metodia CustomerDone, joka antaa WaitForCutToFinish metodissa odottavalle säikeelle luvan jatkaa eteenpäin antamalla tälle viestin notify. Metodia CustomerDone suorittava säie asetetaan odotustilaan odottamaan viestiä siitä, että asiakas on poistunut tuolista. Asiakasproseduuri ilmoittaakin seuraavaksi parturituolinvapautumisesta asettamalla attribuutin barber_chair_free arvoksi TRUE ja kutsumalla Barber-luokan metodia DoNotify, joka vapauttaa CustomerDone metodissa odottavan säikeen. Tämän jälkeen Customer proseduuri antaa seuraavalle odotustuolilla odottavalle asiakkaalle viestin notify päästäen tämän parturin tuolille. Ennen tuolille istuutumista vapauttaa asiakas vielä varaamansa odotustuolin kasvattamalla free_waiting_chairs attribuutin arvoa yhdellä. Tämän jälkeen ohjelma etenee edellä esitetyn mukaisesti.

Jaana Diakite Projekti 1 JAVA-Monitorit 13(13) LÄHTEET Wesley, 2006 Löflund, J. 2002. Edsger Wybe Dijkstra. Helsingin Yliopisto. [WWW-dokumentti]. http://www.cs.helsinki.fi/u/kerola/tkhist/k2002/alustukset/dijkstra/dijkstra.html OSU Oregon State University. [WWW-dokumentti]. http://classes.engr.oregonstate.edu/eecs/fall2002/cs411/barbershop.txt Oulun yliopiston tietojenkäsittelytieteen laitos. Monitorit. [WWW-dokumentti]. http://www.tol.oulu.fi/~avesanen/rinn_ohjelm/luennot/monitorit.html Sun Developer Network. Monitors. http://java.sun.com/developer/books/performance2/chap4.pdf Tampereen teknillinen yliopisto: Ohjelmointikielten periaatteet Luennot [WWW-dokumentti].. http://www.cs.tut.fi/~okp/luennot/kalvot/rinnan06.pdf#search=%22java%20monit orit%22 Universität Paderborn. Monitors in general and in Java [WWW-dokumentti].. Ben-Air, M, Principals of concurrent and distributed programming. Addison- http://ag-kastens.uni-paderborn.de/lehre/material/ppje/folien/comment18-37.2.pdf