Tråder del 2 Våren 2012

Like dokumenter
Stein Gjessing. Institutt for informatikk. Universitetet i Oslo. Institutt for informatikk

Tråder del 2 Våren Stein Gjessing Institutt for informatikk Universitetet i Oslo

Start opp. Prosess 3 Meldingsutveksling Operativsystemet (styrer alt og sørger for kommunikasjon mellom prosesser)

INF1010 Tråder II 6. april 2016

INF1010 Tråder mars 2016

IN1010 våren Repetisjon av tråder. 15. mai 2018

Invarianter, +lstander og li1 mer seman+kk

Sortering med tråder - Quicksort

INF våren 2015

Tråder Repetisjon. 9. og 13. mai Tråder

Tråder Repetisjon. 9. og 13. mai Tråder

UNIVERSITETET I OSLO

INF1010, 22. mai Prøveeksamen (Eksamen 12. juni 2012) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

Operativsystemer, prosesser og tråder

INF1010 Tråder J. Marit Nybakken Motivasjon. Å lage en tråd

INF Notater. Veronika Heimsbakk 10. juni 2012

INF1010 oversikt med

IN Våren 2019 Tråder del mars 2019

Innhold. Introduksjon til parallelle datamaskiner. Ulike typer parallelle arkitekturer. Prinsipper for synkronisering av felles hukommelse

INF Våren 2017 Tråder del 1

Velkommen til. INF våren 2016

INF1010 Repetisjonskurs i tråder

INF2440 Prøveeksamen, løsningsforslag, 20 mai Arne Maus PSE, Inst. for informatikk

INF Våren Li' repe$sjon om Tråder og GUI. Stein Gjessing, Ins$tu' for informa$kk, Universitetet i Oslo. Ins$tu' for informa$kk

Eksamen INF1010 V2009 Del B prøveeksamen V2010 Vekt 60 %

INF1010 oversikt med

Synkronisering I. Kapittel 6. Tråd A. ferdig. t.varsle() u.vente() Tråd B. ferdig. tid

Synkronisering II. Kapittel 7. Betingelse oppfylt (0) liste. tråd-deskriptor. venteliste. tråd-deskriptor. tråd-deskriptor.

2 Om statiske variable/konstanter og statiske metoder.

La oss begynne med en repetisjon av hva som skjer når du kjører Javaprogrammet

Avdeling for ingeniørutdanning Institutt for teknologi

INF1010 våren 2019 Onsdag 30. januar. Mer om unntak i Java (med litt repetisjon av I/O først)

INF1010, 15. januar time. Parametriserte klasser (generiske klasser) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

INF2440 Uke 4, våren2014 Avsluttende om matrisemultiplikasjon og The Java Memory Model + bedre forklaring Radix. Arne Maus OMS, Inst.

I et Java-program må programmøren lage og starte hver tråd som programmet bruker. Er dette korrekt? Velg ett alternativ

Kort notat om parallellstyring IN147

UNIVERSITETET I OSLO

Enkle generiske klasser i Java

INF2440 Uke 6, v2017. Arne Maus PSE, Inst. for informatikk

INF1010, 21. februar Om å gå gjennom egne beholdere (iteratorer) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

GetMutex(lock) { while(testandset(lock)) {} } En context switch kan ikke ødelegge siden testen og endringen av lock skjer i samme instruksjon.

INF1010 våren januar. Objektorientering i Java

UNIVERSITETET I OSLO

INF2440 Uke 6, v2015 om faktorisering av primtall + tre løsninger på et produsent/konsumentproblem. Arne Maus PSE, Inst.

UNIVERSITETET I OSLO

Inf1010 oppgavesamling

INF2100. Oppgaver uke 40 og

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

UNIVERSITETET I OSLO

Fra Python til Java. En introduksjon til programmeringsspråkenes verden. Dag Langmyhr

Side 1 av 11, prosesser, tråder, synkronisering, V. Holmstedt, HiO 2006

INF1010, 21. januar Klasser med parametre = Parametriserte klasser = Generiske klasser

UNIVERSITETET I OSLO

INF1010 våren 2017 Onsdag 25. januar. Litt om unntak i Java

Innhold. Forord Det første programmet Variabler, tilordninger og uttrykk Innlesing og utskrift...49

INF2440 Eksamen 2016 løsningsforslag. Arne Maus, PSE ifi, UiO

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

Forelesning III Kap 8 & 7; Dagsplan. Gjenbruk. Condition synchronization. Gjennomgående eksempler. Kode: Design: Verktøy

INF våren 2017

INF2100. Oppgaver 23. og 24. september 2010

GUI («Graphical User Interface») del 2

Arne Maus OMS, Inst. for informatikk

INF2100. Oppgaver 9. oktober 2012 C 100 X 10

IN1010 våren januar. Objektorientering i Java

Det finnes ingenting. som kan gjøres med interface. men som ikke kan gjøres uten

Kapittel 8: Programutvikling

Prøveeksamen INF2440 v Arne Maus PSE, Inst. for informatikk

INF2100. Oppgaver 6. og 11. oktober 2011 C 100 X 10

Stein Gjessing, Ins$tu' for informa$kk, Universitetet i Oslo

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Del 3: Evaluere uttrykk

Lenkelister. Lister og køer. Kopi av utvalgte sider fra forelesningen.

UNIVERSITETET I OSLO

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

INF2100. Oppgaver 26. september til 1. oktober 2007

INF1010 Eksamenstips. Løsningsforslag prøveeksamen del 1.

INF 1010, vår 2005 Løsningsforslag uke 11

< T extends Comparable<T> > Indre klasser mm. «Det du bør ha hørt om før oblig 4»

INF januar 2015 Stein Michael Storleer (michael) Lenkelister

INF 1000 høsten 2011 Uke september

UNIVERSITETET I OSLO

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

INF2440 Uke 4, v2017 Om å samle parallelle svar, matrisemultiplikasjon og The Java Memory Model + evt bedre forklaring Radix

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Stein Gjessing, Institutt for informatikk, Universitetet i Oslo

1. Krav til klasseparametre 2. Om å gå gjennom egne beholdere (iteratorer) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

Kapittel 9: Sortering og søking Kort versjon

Inf1010 oppgavesamling

IN2010: Algoritmer og Datastrukturer Series 2

4/5 store parallelle maskiner /4 felles hukommelse in 147, våren 1999 parallelle datamaskiner 1. når tema pensum.

Eksekveringsrekkefølgen (del 1) Oppgave 1. Eksekveringsrekkefølgen (del 2) Kommentar til oppgave 1. } // class Bolighus

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): Hva er kompilering?

INF Uke 10. Ukesoppgaver oktober 2012

Litt om Javas class-filer og byte-kode

IN våren 2019 Onsdag 16. januar

IN våren 2018 Tirsdag 16. januar

Dagens forelesning. Java 13. Rollefordeling (variant 1) Rollefordeling (variant 2) Design av større programmer : fordeling av roller.

Transkript:

Tråder del 2 Våren 2012 Stein Gjessing Universitetet i Oslo 1

Repetisjon: Tråder i Java: class MinTråd extends Thread { public void run( ) { while (<mer å gjøre>) { <gjør noe>; try {sleep(<et tall, dvs. en stund>); catch (InterruptedException e) { // end while // end run //end class MinTråd En tråd lages og startes opp slik: run inneholder vanligvis en løkke som utføres til oppgaven er ferdig. MinTråd objekt (en tråd) start run tråden MinTråd tråden; tråden = new MinTråd( ); tråden.start( ); Her går den nye og den gamle tråden (dette programmet), vider hver for seg start( ) er en metode i Thread som må kalles opp for å få startet tråden. start-metoden vil igjen kalle metoden run (som vi selv programmerer). 2

Kommunikasjon mellom tråder: Felles data Felles data (blå felt, F) må vanligvis bare aksesseres (lese eller skrives i) av en tråd om gangen. Hvis ikke blir det kluss i dataene. Et felles objekt kalles en monitor. Metodene i en monitor har modifikatoren synchronized f.eks. K F F K Produsenter put hent Buffer Konsumenter K: konstante data Monitor er ikke noe ord i Java 3

Basale Java- verktøy: synchronized, wait(), no$fy() og no$fyall() (metodene er definert i class Object) produsenter while ( ) { <lag noe>; p.putinn(...); synchronized void putinn( int verdi) while (full) wait(); // nå er bufferet ikke fult < legg inn> synchronized int hentut konsumenter while ( ) { p.hentut <bruk de'e>; while ( ) { <lag noe>; p.putinn(...); If (empty) return null; else <ta ut et element> // nå er bufferet ikke fult no3fy(); return element; En monitor (et objekt) while ( ) { p.hentut <bruk de'e>; Pass på: polling (prøve om og om igjen (uten å få gjort noe)) 4

To køer i en basal Java monitor: En kø av ventende tråder på hele monitoren kø for å få låsen ($lgang $l monitoren) ventende tråder synchronized void putinn( int verdi) while (full) wait(); // nå er bufferet ikke fult < legg inn> synchronized int hentut If (empty) return null; else <ta ut et element> // nå er bufferet ikke fult no3fy(); return element; En kø av ventende tråder på wait - instruksjoner (wait- set). Startes av no$fy () og/eller no$fyall() Legges da i den andre køen (først?? (ingen garan$)) Derfor er det nødvendig med while En monitor (et objekt) 5

Java har én kø for alle wait()- instruksjonene på samme objekt! kø for å få låsen ventende tråder produsenter while ( ) { <lag noe>; p.putinn(...); while ( ) { <lag noe>; p.putinn(...); synchronized void putinn( int verdi) while (full) wait(); // nå er bufferet ikke fult < legg inn> // nå er bufferet ikke fullt no3fy(); synchronized int hentut while (empty) wait(); // nå er bufferet ikke tomt <ta ut et element> // nå er bufferet ikke fult no3fy(); return element; konsumenter while ( ) { p.hentut <bruk de'e>; while ( ) { p.hentut <bruk de'e>; En monitor (et objekt) Pass på: Unngå vranglås 6 (deadlock)

kø for å få låsen Flytt en: notify (); ventende tråder int ledig = totres; //invariant: 0 <= ledig <= totres synchronized void reserver( int antall) while (ledig < antall) wait(); // nå er det nok ledig ledig = ledig antall; synchronized void frigi(int antall) ledig = ledig + antall; // nå er mange flere ledig no3fyall(); En monitor (et objekt) for å reservere og frigi et antall like resurser Hvis du ikke er HELT sikker på at enhver ventende tråd kan ordne skikkelig opp må du si: notifyall(); Flytt alle: notifyall (); Da blir ALLE ventende tråder flyttet opp til køen for å få låsen Men hva med rettferdighet (fairness)?? 7

Eksempel på parallellisering: Finn minste tall i tabell (samme teknikk for å finne sum / gjennomsnitt) Hovedprogrammet starter N tråder og venter på at de alle er ferdige før det henter minste verdi fra monitoren MinstVerdi Tråd 1 finner minste tall i denne delen av tabellen Tråd 2 finner minste tall i denne delen av tabellen synchronized void giminsteverdi( int verdi) synchronized int hentminst Objekt av klassen MinstVerdi Trådenes minste verdi gis $l monitoren Tråd n (64?) finner minste tall i denne delen av tabellen BARE FANTASIEN SETTER GRENSER 8

Amdahls lov En beregning delt opp i parallell går fortere jo mer uavhengig delene er Amdahls lov: Total$den er $den i parallell + $den det tar å kommunisere / synkronisere/ gjøre felles oppgaver Tiden det tar å synkronisere er ikke parallelliserbar (hjelper ikke med flere prosessorer) total tid Start opp Synkroniser Lag resultat Parallell beregning Parallell beregning 9

Amdahls lov og finn minste tall Total$d: Tiden det tar å lage 64 og se'e i gang 64 tråder (kan det gjøres i parallell?) (log 64 = 6) Tiden det tar å finne et minste tall i min del av tabellen Til slu' i monitoren: En og en tråd må teste si' resultat (Kan det gjøres i parallell?) 2 Start med en tråd, vha. 6 doblinger har vi 64 tråder, dvs, 2 = 64, og log 64 = 6 6 2 2, 4, 8, 16, 32, 64 10

Hovedprogrammet versjon 1 public class MinstR { final int maxverdiint = Integer.MAX_VALUE; int [ ] tabell; MinstMonitor monitor; public static void main(string[ ] args) { new MinstR(); public MinstR ( ) { tabell = new int[640000]; for (int in = 0; in< 640000; in++) tabell[in] = (int)math.round(math.random()* maxverdiint); monitor = new MinstMonitorR(); for (int i = 0; i< 64; i++) // Lag og start 64 tråder new MinstTradR(tabell,i*10000,((i+1)*10000)-1,monitor).start(); monitor.vent(); System.out.println("Minste verdi var: " + monitor.hentminste()); Monitor for resultater og synkronisering interface MinstMonitor { void vent(); void giminsteverdi (int minverdi); int hentminste (); 11

class MinstMonitorR implements MinstMonitor { private int minsttilna = Integer.MAX_VALUE; private int antallferdigesubtrader = 0; public synchronized void vent() { while (antallferdigesubtrader!= 64) { try {wait(); System.out.println(antallFerdigeSubtrader + " ferdige subtråder "); catch (InterruptedException e) { System.out.println(" Uventet avbrudd "); System.exit(1); // antall ferdige subtråder er nå 64 public synchronized void giminsteverdi (int minverdi) { antallferdigesubtrader ++; if(minsttilna > minverdi) minsttilna = minverdi; if(antallferdigesubtrader == 64) notify(); // eller hver gang, (men stort sett unødvendig): notify(); public synchronized int hentminste () { return minsttilna; 12

Tråder som finner minste tall i del av tabellen class MinstTradR extends Thread { int [ ] tab; int startind, endind; MinstMonitor mon; MinstTradR(int [ ] tb, int st, int en, MinstMonitor m) { tab = tb; startind = st; endind = en; mon = m; public void run(){ int minverdi = Integer.MAX_VALUE; for ( int ind = startind; ind <= endind; ind++) if(tab[ind] < minverdi) minverdi = tab[ind]; // denne tråden er ferdig med jobben: mon.giminsteverdi(minverdi); // slutt run // slutt MinstTradR 13

Barrierer i parallellprogrammering Barriere, dvs. vent på at alle er ferdig Denne tråden kan fortsetter når alle har nådd barrieren (join) Gren opp i parallell beregning (fork) Alle trådene sier fra når de er ferdige tid 14

Barrierer i parallellprogrammering import java.util.concurrent.*; Barrieren CountDownLatch minbariere = new CountDownLatch(6) minbarriere.await(); minbarriere.countdown(); tid 15

Barrieren i de'e eksemplet Start opp Gren opp i parallell beregning (fork) Alle trådene sier fra når de er ferdige (har nådd barrieren) Barieren Denne tråden kan fortsetter når alle har nådd barrieren (join). Da er det endelige resultatet klart. Alle trådene avsluttes med å kalle en metode i en og samme monitor tid 16

Hovedprogrammet versjon med barriere import java.util.concurrent.*; public class MinstB { final int maxverdiint = Integer.MAX_VALUE; int [ ] tabell; final int antalltrader = 64; MinstMonitor monitor = new MinstMonitorB();; CountDownLatch minbarriere = new CountDownLatch(antallTrader); public static void main(string[ ] args) { new MinstB(); public MinstB ( ) { tabell = new int[640000]; for (int in = 0; in< 640000; in++) tabell[in] = (int)math.round(math.random()* maxverdiint); for (int i = 0; i< antalltrader; i++); // Lag og start antalltrader tråder new MinstTradB(tabell,i*10000,((i+1)*10000)-1,monitor,minBarriere).start(); //vent på at alle trådene er ferdig: try { minbarriere.await(); // vent på at alle Minst-trådene har nådd barrieren System.out.println("Minste verdi var: " + monitor.hentminste() ); catch (InterruptedException ex){ 17

class MinstMonitorB implements MinstMonitor { private int minsttilna = Integer.MAX_VALUE; Monitor for resultater public void vent(){ // brukes ikke. Bruker barriere isteden. public synchronized void giminsteverdi (int minverdi) { if(minsttilna > minverdi) minsttilna = minverdi; public synchronized int hentminste () {return minsttilna; 18

Tråder som finner minste tall i del av tabellen class MinstTradB extends Thread { int [ ] tab; int startind, endind; CountDownLatch barriere; MinstMonitor mon; MinstTradB(int [ ] tb, int st, int en, MinstMonitor mon, CountDownLatch barriere) { tab = tb; startind = st; endind = en; this.mon = mon; this.barriere = barriere; public void run(){ int minverdi = Integer.MAX_VALUE; for ( int ind = startind; ind <= endind; ind++) if(tab[ind] < minverdi) minverdi = tab[ind]; // gi minste resultat til monitoren: mon.giminsteverdi(minverdi); // signaler at denne tråden er ferdig med jobben: barriere.countdown(); // sier fra at jeg har nådd barrieren // slutt run // slutt MinstTradB 19

Maskinarkitektur, f.eks. 4 prosessorer prosessor registre cache 1 cache 2 prosessor registre cache 1 Minne (RAM) prosessor registre cache 1 cache 2 prosessor registre cache 1 20

Javas minnemodell (memory model) En minnemodel defineres ved å se på lovlige rekkefølger av lese og skriveoperasjoner på variable. Innad i en tråd skjer $ng i rekkefølgen gi' av programmet, bortse' fra av at uavhengige operasjoner kan re- ordnes (for op$malisering). Mellom tråder skjer $ng ikke i rekkefølge unta' Ved bruk av vola$le variable Alle operasjoner før en unlock skjer i rekkefølge før alle operasjoner e'er en e'erfølgende lock på den samme monitoren. 21

Vola$le variable en variabel som er deklarert vola$le caches ikke (og oppbevares ikke i registre). En vola$l variable skrives helt $lbake i primærlageret før neste instruksjon uoøres. Rekkefølgen av skriv/les- operasjoner på vola$le variable og låsing/opplåsing av låser definerer en sekensielt konsistent rekkefølge av alle operasjoner som er en del av seman$kken $l programmeringsspråket Java 22

Synkronisering og felles variable Synchroniza$on ensures that memory writes by a thread before or during a synchronized block are made visible in a predictable manner to other threads which synchronize on the same monitor. Aper we exit a synchronized block, we release the monitor, which has the effect of flushing the cache to main memory, so that writes made by this thread can be visible to other threads. Before we can enter a synchronized block, we acquire the monitor, which has the effect of invalida$ng the local processor cache so that variables will be reloaded from main memory. We will then be able to see all of the writes made visible by the previous release. From: JSR 133 (Java Memory Model) FAQ Jeremy Manson and Brian Goetz, February 2004 23

Synkronisering og felles variable This means that any memory opera$ons which were visible to a thread before exi$ng a synchronized block are visible to any thread aper it enters a synchronized block protected by the same monitor, since all the memory opera$ons happen before the release, and the release happens before the acquire. From: JSR 133 (Java Memory Model) FAQ Jeremy Manson and Brian Goetz, February 2004 24

Og fra definisjonen av Java: Versjon 3 side 579: 17.7 Non- atomic Treatment of double and long Some implementa$ons may find it convenient to divide a single write ac$on on a 64- bit long or double value into two write ac$ons on adjacent 32 bit values. For efficiency's sake, this behavior is implementa$on specific; Java virtual machines are free to perform writes to long and double values atomically or in two parts. For the purposes of the Java programming language memory model, a single write to a non- vola$le long or double value is treated as two separate writes: one to each 32- bit half. This can result in a situa$on where a thread sees the first 32 bits of a 64 bit value from one write, and the second 32 bits from another write. Writes and reads of vola3le long and double values are always atomic. Writes to and reads of references are always atomic, regardless of whether they are implemented as 32 or 64 bit values. VM implementors are encouraged to avoid spliwng their 64- bit values where possible. Programmers are encouraged to declare shared 64- bit values as vola3le or synchronize their programs correctly to avoid possible complica$ons. 25

Mer fra definisjonen av Java: Versjon 3 side 579: For example, in the following (broken) code fragment, assume that this.done is a non- vola$le boolean field: while (!this.done) Thread.sleep(1000); The compiler is free to read the field this.done just once, and reuse the cached value in each execu$on of the loop. This would mean that the loop would never terminate, even if another thread changed the value of this.done. 26

Fordelen med konstanter (immutable objects) Konstanter kan det aldri skrives $l Minnemodellen for konstanter blir derfor veldig enkel. Prøv å ha mest mulig konstanter når data skal deles mellom tråder. Eksempel: Geografiske data, observasjoner Hvis du ønsker å gjøre en forandring: Kast det gamle objektet og lag et ny'. 27

Prosesser og tråder P1 P2 Pn P1 P2 Pm Operativsystemet (styrer alt og sørger for kommunikasjon mellom prosesser) Operativsystemet (styrer alt og sørger for kommunikasjon mellom prosesser) Datamaskin 1 Datamaskin 2 28

Kommunikasjon mellom prosesser Samarbeidende prosesser sender meldinger til hverandre (brune piler, mest vanlig) eller leser og skriver i felles lager (blå piler). Prosess 1 Prosess 2 Meldingsutveksling Prosess 3 Prosess 1 Prosess 2 Prosess 3 Felles data 29

Kommunikasjon mellom Java- prosesser: RMI: Remote Method Invoca$on (Norsk: Fjern- metode- kall) Et Java program (på en maskin) InterfaceNavn fjernpeker =.; Dette ønsker vi å oppnå: Et annet Java program (på en annen maskin)... fjernpeker.metodenavn( );... metodenavn objekt av en klasse som implementerer InterfaceNavn Alternativt navn: RPC: Remote Procedure Call 30

En maskin fjernpeker RMI: Implementasjon en proxy for fjern-objektet (bak kulissene) et skjelett formidler kall og retur Ikke pensum i INF1010 En annen maskin metodenavn tjenermetode... fjernpeker.metodenavn( );... en stub for fjern-metoden Odene proxy og stub brukes ikke alltid like konsistent fjern-objekt (kan også brukes av Javaprogrammet på denne maskinen) Parametere (og returverdi) pakkes ned og sendes mellom de to maskinen (marshaling) 31

RMI: Hvordan kalle metoder i (Java- )objekter på andre maskiner klient 3. oppgi navn på objekt tjener Ikke pensum i INF1010 Register/ navnetjener 4. og få tilbake peker 2. 5. bruk peker til fjernmetode-kall (Remote Method Invocation): fjernpeker.metodenavn( ); objekt 1. registrer (bind) med navn på objektet Og det eneste som er kjent på begge maskinene er Interfacet til objektet og navnet 32

CORBA, MPI CORBA (Common Object Request Broker Architecture) er en språkuavhengig måte å definere kommunikasjon mellom ern- objekter (a la side 29-31) Et IDL (Interface Defini$on Language) definerer grensesni'et $l objektene (på samme måte som Interface i Java) En IDL- kompilator overse'er $l di' valgte språk (Java, C++, C#, Smalltalk, ) De'e gjør at prosesser skrevet i forskjellige objektorienterte språk og som kjører på forskjellige (eller samme) maskin kan kommunisere. Språk som ikke er objektorienterte: Send en melding (MPI Message- Passing Interface) P1 P2 P3 33

Time out fra tråder To typer invarianter: Når du lager en løkke er det all$d en invariant som sier hvor langt arbeidet i løkka er kommet Data i et objekt er all$d styrt av en (eller flere) invarianter eller konsistensregler De to neste sidene innholder eksempler på de'e Viktig pensum i INF1010 34

Invarianter på data i løkker Eksempel: Finne minste verdi i tabell // Vi vet ingenting annet enn at tabell [0] til og med // tabell[999] inneholder tall. Vi skal finne det minste int minsttilnaa = tabell[0]; Inv(0) 0 // minsttilnaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[0] for (indeks = 1; indeks < 1000; indeks ++) { // minsttilnaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[indeks-1] if (minsttilnaa > tabell [indeks] ) minsttilnaa = tabell[indeks] Inv(indeks) Inv(indeks-1) // minst TilNaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[indeks] // Nå er indeks == 1000 // minsttilnaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[indeks-1] // Da følger: // minsttilnaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[999]!!!!!!! Hvis Inv(indeks) er sant og vi utfører: indeks ++ så er etterpå Inv(indeks-1) sant! 35 999

Invarianter på data i objekter Invariant: Alle dataene vi lagrer ligger i tabell[0] til og med tabell [antall 1] og 0 <= antall <= 1000 0 settinn(x) { if (antall == 1000) return ; antall ++; tabell[antall-1] = x; antall taut ( ) { if (antall == 0) return null; antall --; return (tabell[antall]); Overbevis deg (og andre) om at metodene bevarer Invarianten!!!!!!!!!!!!!!!!!!!!! 999 36

Vi tar opp tråden (J ) fra sidene foran og fra side 7: Hvordan bevare invarianter på data i objekter når vi ikke har ansvaret alene. Svar: Vi venter o*e på at andre skal gjøre objektets (monitorens) 9lsand hyggeligere. synchronized void setinn(int verdi) If (antall == 1000) vent- $l: Ikke- Full(); antall++; : no$fy: Ikke- Tom(); venter på å komme inn første gang synchronized int taut() If (antall == 0) vent- $l: Ikke- Tom(); antall - - ; : no$fy: Ikke- Full(); En monitor (et objekt) Invariant: Alle dataene vi lagrer ligger i tabell[0] til og med tabell [antall 1] og 0 <= antall <= 1000 37

Java: Flere køer av ventende tråder Lock laas = new ReentrantLock(); Condi3on ikkefull = laas.newcondi$on(); Condi3on ikketom = laas.newcondi$on(); void se'inn ( int verdi) laas.lock(); try { while (full) ikkefull.await(); // nå er det helst sikkert ikke fult : // det er lagt inn noe, så det er // helt sikkert ikke tomt: ikketom.signal(); finally { laas.unlock() int taut ( ) En kø for selve låsen og en kø for hver condi$on- variabel (import java.concurrent.locks.*) Metodene er ikke lenger synchronized men vi må låse (og låse opp!) monitoren selv. 38

Interface Condi3on Java API void await() Causes the current thread to wait un$l it is signalled (or interrupted) void signal() Wakes up one wai$ng thread. Class ReentrantLock er en lås og en fabrikk som lager objekter som implementerer grensesni'et Condi$on (på denne låsen) 39

Lock laas = new ReentrantLock(); Condi3on ikkefull = laas.newcondi$on(); Condi3on ikketom = laas.newcondi$on(); void se'inn ( int verdi) throws InterrupedExcep$on laas.lock(); try { while (full) ikkefull.await(); // OK med if? // nå er det helst sikkert ikke fult : // det er lagt inn noe, så det er helt sikkert ikke tomt: ikketom.signal(); finally { laas.unlock(); int taut ( ) throws InterrupedExcep$on laas.lock(); try { while (tom) ikketom.await(); // OK med if? // nå er det helst sikkert ikke tomt; : // det er det ta' ut noe, så det er helt sikkert ikke fult: ikkefull.signal(); finally { laas.unlock(); Nå har vi en kø per betingelse som skal oppfylles (og vi kan til og med få rettferdighet!) Bra! 40

Legg merke $l bruken av finally void putinn (int verdi) throws InterrupedExcep$on { laas.lock(); try { : : finally { laas.unlock(); Da blir laas.unlock() all3d uoørt!! 41