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

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

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

Rinnakkaisohjelmointi, Syksy 2006

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

Projekti 1 Säikeet ja kriittisen vaiheen kontrollointi javalla

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

Ohjelmoinnin peruskurssien laaja oppimäärä

RINNAKKAINEN OHJELMOINTI A,

Monitorit -projekti Rinnakkaisohjelmointi

T Henkilökohtainen harjoitus: FASTAXON

Mikä yhteyssuhde on?

14. Poikkeukset 14.1

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

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

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Olio-ohjelmointi Javalla

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

14. Poikkeukset 14.1

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

10 Lock Lock-lause

Rajapinta (interface)

HOJ Säikeet (Java) Ville Leppänen. HOJ, c Ville Leppänen, IT, Turun yliopisto, 2012 p.1/55

Tehtävä 1. Tehtävä 2. Arvosteluperusteet Koherentti selitys Koherentti esimerkki

Graafisen käyttöliittymän ohjelmointi Syksy 2013

Luokan sisällä on lista

Johdatus Java 1.5:n semaforeihin

Ohjelmointi 2 / 2010 Välikoe / 26.3

812315A Ohjelmiston rakentaminen. Asynkronisuus

1.3Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

9. Periytyminen Javassa 9.1

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

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

Periytyminen (inheritance)

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

9. Periytyminen Javassa 9.1

1 Tehtävän kuvaus ja analysointi

1.3 Lohkorakenne muodostetaan käyttämällä a) puolipistettä b) aaltosulkeita c) BEGIN ja END lausekkeita d) sisennystä

Ohjelmoinnin peruskurssien laaja oppimäärä

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

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Tietokannat II -kurssin harjoitustyö

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

Metodien tekeminen Javalla

Pino S on abstrakti tietotyyppi, jolla on ainakin perusmetodit:

Olio-ohjelmointi Virhetilanteiden käsittely

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

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Poikkeukset ja tietovirrat: Virhetilanteiden ja syötevirtojen käsittely

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

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

Java ja grafiikka. Ville Sundberg

Poikkeustenkäsittely

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

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

Listarakenne (ArrayList-luokka)

Pakkauksen kokoaminen

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

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

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

JAVA on ohjelmointikieli, mikä on kieliopiltaan hyvin samankaltainen, jopa identtinen mm. C++

7. Oliot ja viitteet 7.1

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

public static void main (String [] args)

Taulukoiden käsittely Javalla

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

JAVA-OHJELMOINTI 3 op A274615

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

YHTEYSSUHDE (assosiation)

11. Javan toistorakenteet 11.1

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

16. Javan omat luokat 16.1

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

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

Toisessa viikkoharjoituksessa on tavoitteena tutustua JUnit:lla testaukseen Eclipse-ympäristössä.

Ohjelmointi 2 / 2011 Välikoe / 25.3

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

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

1. Omat operaatiot 1.1

Pakkauksen kokoaminen

20. Javan omat luokat 20.1

Ehto- ja toistolauseet

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

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Pakkaukset ja määreet

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena

1. Mitä tehdään ensiksi?

Javan GUI Scratchaajalle

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

11. Javan valintarakenteet 11.1

Sisältö Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 26.2

Ohjelmointi 1 / 2009 syksy Tentti / 18.12

Java kahdessa tunnissa. Jyry Suvilehto

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

JavaRMI 1 JAVA RMI. Rinnakkaisohjelmoinnin projekti 1 osa C Tekijät: Taru Itäpelto-Hu Jaakko Nissi Mikko Ikävalko

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

Laskennallisesti Älykkäät Järjestelmät. Sumean kmeans ja kmeans algoritmien vertailu

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena

Luokat ja oliot. Ville Sundberg

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

OSA I: Yhteisten muuttujien käyttö. Prosessit samassa koneessa. Rio 2004 / Auvo Häkkinen 2-1

OSA I: Yhteisten muuttujien käyttö. Sisältöä. Prosessit samassa koneessa. Poissulkeminen ja synkronointi. Semaforit ja rinnakkaisuuden hallinta

Transkriptio:

Javan semaforit Joel Rybicki, Aleksi Nur mi, Jara Uitto 16.12.2007 Helsingin yliopisto Tietojenkäsittelytieteen laitos Tätä ohjetta saa käyttää ja jatkokehittää opetustarkoituksiin.

Javan semaforitoteutus Semafori on olio, joka ratkaisee kriittisen vaiheen ongelman ohjelmoijan kannalta helpo m min. Kriittistä vaihetta vartioimaan luodaan se mafori. Jokaisessa prosessissa kriittisen vaiheen suoritus ym päroidään se maforiin liittyvillä funktiokuts uilla. Funktiokutsuja on kaksi ja näistä käytetään useita nimityksiä, kuten wait/ signal, P/ V, acquire/ release, pend/ post tai up/ down. Semafori pitää huolen, että kriittiseen vaiheeseen pääsee kerrallaan vain ohjelmoijan asetta ma m äärä prosesseja. Semaforin nimi tulee rautatieliikenteessä käytetyistä siipiopastimista, joilla ratkaistiin sa ma ongelma käytännössä. Semaforin luonti Javassa se mafori on toteutettu luokkana Semaphore. Tämä alustetaan pitkälti sa - m oin kuten luentojen ja kirjan esimerkkise maforit. Aluksi m ääritellään se maforin "alkutila" eli kuinka m o nta prosessia kerrallaan pääsee se maforista läpi. Binäärise mafori eli m uteksi voidaan toteuttaa alusta malla se maforin "lupalappujen" (per mits) m ääräksi yksi. Konstruktoreita on kaksi. Semaphore(int per mits) Creates a Semaphore with the given n u m ber of per mits an d nonfair fairness setting. Semaphore(int per mits, boolean fair) Creates a Semaphore with the given n u m ber of per mits and the given fairness setting. Semaphore - luokan konstruktorille voidaan antaa myös boolean - tyyppinen fairpara metri. Tämä m äärittelee onko se mafori vah va eli reilu vai heikko eli epäreilu. Vahvan se maforin odotusjono on first in, first out - tyyppinen (jono). Kun fairpara metri on false, odotusjono on järjestä mätön joukko. Tällöin odottavien pro - sessien joukosta s uoritukseen valitaan mikä tahansa joukkoon kuuluva prosessi. Tällöin se mafori on heikko ja nälkiintyminen on m a h dollista. Mikäli fair- para metria ei anneta, se mafori on oletuksena heikko.

Wait ja signal Kirjan ja luentojen wait ja signal - operaatioita vastaavat Javassa acquire ja release. Nämä metodit toimivat vastaavasti kuin luennon esimerkeissä. Acquire vähentää se maforin laskurista yhden ja laittaa prosessin jonoon mikäli laskurin arvo meni alle nollan. Release toimii kuten signal eli mikäli se maforin jonossa ei ole ketään, lisätään laskuriin yksi, m u uten päästetään yksi prosessi jonosta jatkam aan. Oleellisin ero on kirjan ja luentojen vastaaviin operaatioihin on, että acquire- m etodi heittää InterruptedException - poikkeuksen, joka tulee kaapata (koodista tulee hiukan pide m pää). void acquire() throws Interrupte dexception Acquires a per mit from this se ma p hore, blocking u ntil one is available, or the thread is interrupted. void release() Releases a per mit, returning it to the se ma phore. Javan API ei erikseen m äärittele, onko Semaphore - luokan toteut us busy - wait - tyyppinen. Nykyisin Java käyttää sisäisesti käyttöjärjestelmien m o niajopalveluita, joten se mafori varmastikin asettaa säikeet s uspend - tilaan. Eksoottisim mista laite - ja käyttöjärjestelmäym päristöistä tai hyvin vanhoista Java - versioista ei kuitenkaan voi mennä takuuseen. Esimerkit Esimerkki: Mutex lukko binäärisemaforilla public Process extends Thread { // Binäärisemafori, joka toimii mutex lukkona private static Semaphore mutex = new Semaphore(1); public void run() { while(true) { // Rinnakkaistettua laskentaa.. //.. //.. // Prosessi haluaa siirtyä kriittiseen vaiheeseen try { mutex.acquire(); catch (InterruptedException e) {

// Kriittinen vaihe! // Vain yksi prosessi kerrallaan voi suorittaa tätä. criticalsection(); // Kriittinen vaihe ohi. Vapautetaan mutex lukko mutex.release(); // Ja jatketaan laskentaa.. Esimerkki: Java toteutus Ben Arin kirjan algoritmista 6.11 /* Java adaption of algorithm 6.11 (Ben Ari). */ import java.util.concurrent.semaphore; import java.util.random; public class Philosopher extends Thread { // The amount of philosophers (and forks) protected static final int PHILOSOPHER_COUNT = 4; protected static final int FORK_COUNT = PHILOSOPHER_COUNT; // Maximum time for thinking or eating protected static final int MAX_IDLE_TIME = 5000; // Semaphores protected static Semaphore[] forks = new Semaphore[FORK_COUNT]; protected static Semaphore room = new Semaphore(FORK_COUNT); protected static Random rng = new Random(); // Used by spendtime() // Philosopher data protected int id; public Philosopher(int id) { this.id = id; /* Tell the world what I am currently doing. */ protected void Iam(String s) { System.out.println("Philosopher #"+id+" is " + s); /* Spends at least 'max' milliseconds doing nothing */ protected void spendtime(int max) { int time = (int)(rng.nextfloat()*max); try { sleep( max ); catch(interruptedexception e) { /* Spend some time thinking */

protected void think() { Iam("thinking."); spendtime(max_idle_time); Iam("hungry."); /* Get into the dining room then grab forks on the left and right side. * Spend some time eating then release the forks. */ protected void eat() { Iam("entering the room."); // Semaphore.acquire() may throw InterruptedException! try { room.acquire(); // Get into the dining room grabfork(id); grabfork(id+1); catch (InterruptedException e) { Iam("eating."); spendtime(max_idle_time); Iam("done eating."); // Signal the semaphores returnfork(id); returnfork(id+1); room.release(); // Get out of the room /* Grab a fork */ protected void grabfork(int i) throws InterruptedException { if (i == FORK_COUNT) i = 0; forks[i].acquire(); Iam("holding fork " + i + "."); /* Return a fork */ protected void returnfork(int i) { if (i == FORK_COUNT) i = 0; Iam("releasing fork " + i + "."); forks[i].release(); /* Repeat forever.. */ public void run() { while (true) { think(); eat(); // main public static void main(string[] args) { // Initialize the semaphores room = new Semaphore(PHILOSOPHER_COUNT 1, true); for(int i = 0; i<forks.length; i++) {

forks[i] = new Semaphore(1); // Create dining philosophers for(int j = 0; j<philosopher_count; j++) { System.out.println("Philosopher #"+j+" is born!"); Philosopher p = new Philosopher(j); p.start(); Esimerkki: Itsetehty busy wait semafori // Esimerkkitoteutus busy wait semaforista Javalla // Toteutus on heikko eli epäreilu, sillä virtuaalikoneen // skeduloija päättää suoritusjärjestyksen. public class BusyWaitSemaphore { // // Apuluokka, joka hoitaa laskurin synkronoinnin protected class SynchronizedPermitCounter { int value; public SynchronizedPermitCounter(int value) { this.value = value; public synchronized void increase() { this.value++; public synchronized void decrease() { this.value ; public synchronized int getvalue() { return this.value; // protected SynchronizedPermitCounter permits; public BusyWaitSemaphore(int permits) { this.permits = new SynchronizedPermitCounter(permits); // Synchronized päästää vain yhden säikeen kerrallaan suorittamaan // tätä metodia. // Samanaikaiset kutsujat blokataan (siirtyvät suspend tilaan). // Toteutus on jossain määrin reilu. Ensimmäinen odottaja pääsee // ensimmäisenä läpi, // sillä vain yksi säie voi olla kerrallaan suorittamassa metodia (ja while // silmukkaa). public synchronized void acquire() { while ( this.permits.getvalue() <= 0 ) { // Busy wait! this.permits.decrease();

public void release() { this.permits.increase(); Esimerkki: Aterioivat filosofit itsetehdyllä busy wait semaforilla /* Java adaption of algorithm 6.11 (Ben Ari). */ import java.util.random; public class BusyPhilosopher extends Thread { // The amount of philosophers (and forks) protected static final int PHILOSOPHER_COUNT = 5; protected static final int FORK_COUNT = PHILOSOPHER_COUNT; // Maximum time for thinking or eating protected static final int MAX_IDLE_TIME = 5000; // BusyWaitSemaphores protected static BusyWaitSemaphore[] forks = new BusyWaitSemaphore[FORK_COUNT]; protected static BusyWaitSemaphore room = new BusyWaitSemaphore(FORK_COUNT); protected static Random rng = new Random(); // Philosopher data protected int id; public BusyPhilosopher(int id) { this.id = id; /* Tell the world what I am currently doing. */ protected void Iam(String s) { System.out.println("Philosopher #"+id+" is " + s); /* Spends at least 'max' milliseconds doing nothing */ protected void spendtime(int max) { int time = (int)(rng.nextfloat()*max); try { sleep( max ); catch(interruptedexception e) { /* Spend some time thinking */ protected void think() { Iam("thinking."); spendtime(max_idle_time); Iam("hungry."); /* Get into the dining room then grab forks on the left and right side.

* Spend some time eating then release the forks. */ protected void eat() { Iam("entering the room."); room.acquire(); // Get into the dining room grabfork(id); grabfork(id+1); Iam("eating."); spendtime(max_idle_time); Iam("done eating."); returnfork(id); returnfork(id+1); room.release(); // Get out of the room /* Grab a fork */ protected void grabfork(int i) { if (i == FORK_COUNT) { i = 0; forks[i].acquire(); Iam("holding fork " + i + "."); /* Return a fork */ protected void returnfork(int i) { if (i == FORK_COUNT) { i = 0; Iam("releasing fork " + i + "."); forks[i].release(); /* Repeat forever.. */ public void run() { while (true) { think(); eat(); // main public static void main(string[] args) { // Initialize the semaphores room = new BusyWaitSemaphore(PHILOSOPHER_COUNT 1); for(int i = 0; i<forks.length; i++) { forks[i] = new BusyWaitSemaphore(1); // Create dining philosophers for(int j = 0; j<philosopher_count; j++) { System.out.println("Philosopher #"+j+" is born!"); BusyPhilosopher p = new BusyPhilosopher (j);

p.start(); Lisätietoa Semaphore - luokan API: htt p: / / java.sun.com / j2se / 1.5.0 / docs / a pi /java / u til /concurrent /Sema phore.ht ml Javan säikeistyksestä: http: / / www.jguru.com /faq /view.jsp?eid =143462 Semaphore - luokka ei ole ainoa keino hallita rinnakkaisuutta Javassa. Katso myös avainsana synchronized ja rajapinnan Lock toteuttavia luokkia.