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

Like dokumenter
Sortering med tråder - Quicksort

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

INF1010 Sortering. Marit Nybakken 1. mars 2004

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

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

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

INF1000. Marit Nybakken 10. februar 2004

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

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

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

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

INF1010 Repetisjonskurs i tråder

INF1000 Behandling av tekster

UNIVERSITETET I OSLO

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

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

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

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

Jentetreff INF1000 Debugging i Java

INF1010 våren 2018 tirsdag 23. januar

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

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

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

UNIVERSITETET I OSLO

TOD063 Datastrukturer og algoritmer

GUI («Graphical User Interface») del 2

INF1010 Tråder II 6. april 2016

Forkurs INF1010. Dag 1. Andreas Færøvig Olsen Tuva Kristine Thoresen

UNIVERSITETET I OSLO

INF Notater. Veronika Heimsbakk 10. juni 2012

Forelesning inf Java 4

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

Eksempel 1 Eksempel 2 Dramatisering. INF1000 uke 3. Sundvollen 7. september 2015 Dag Langmyhr. INF1000 Sundvollen

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

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

UNIVERSITETET I OSLO

Gjennomgang prøveeksamen oppgave 1, 2, 4, 5, 7

Avdeling for ingeniørutdanning Institutt for teknologi

UNIVERSITETET I OSLO

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

INF1000 Metoder. Marit Nybakken 16. februar 2004

Forelesning inf Java 5

Forelesning inf Java 5

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

Argumenter fra kommandolinjen

Innlesning fra tastatur med easyio. INF1000 høst Vi må først skrive i toppen av programmet: import easyio.*;

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

INF1000 oppgaver til uke 38 (17 sep 23 sep)

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

programeksempel Et større En større problemstilling Plan for forelesingen Problemstillingen (en tekstfil) inneholdt ordet "TGA"

UNIVERSITETET I OSLO

INF Uke 10. Ukesoppgaver oktober 2012

TDT4100 Objektorientert programmering

Operativsystemer, prosesser og tråder

UNIVERSITETET I OSLO

Konstruktører. Bruk av konstruktører når vi opererer med "enkle" klasser er ganske ukomplisert. Når vi skriver. skjer følgende:

Løsningsforslag til eksamen i INF1000 våren 2006

Løsningsforslag ukeoppg. 3: sep (INF Høst 2011)

INF1010 MVC i tekstbaserte programmer

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

INF1010 Hashing. Marit Nybakken 8. mars 2004

UNIVERSITETET I OSLO

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

static int ant_steiner; //antall steiner static int teller2 = 0; //teller for printing til Thread^ murer; //murertråden

Mer objektorientert programmering

INF1010 Rekursjon. Marit Nybakken 1. mars 2004

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

UNIVERSITETET I OSLO

En klasse er noe - en metode gjør noe (! / # <= (! * +!! ",-' %. "- -/ %.!#) )! " 0'%! * *$! "1-)) '' % '. 22!'( 7/ /! * 2 2! "*"% 8"%% 9 - -!

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

Klasser, objekter, pekere og UML. INF gruppe 13

Løse reelle problemer

Programmering i C++ Løsningsforslag Eksamen høsten 2005

INF1000 (Uke 5) Mer om løkker, arrayer og metoder

INF 1000 Prøveeksamen. 23. november Ole Christian og Arne. Oppgave 1 (10 poeng) Er disse programsetningene lovlige i Java? Oppgave 2 (10 poeng)

Eksempel: Body Mass Index (BMI) Forelesning inf Java 3. Ferdig program (første del) Ferdig program (siste del)

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

IN Notat om I/O i Java

INF 1000 høsten 2011 Uke september

INF1000 Uke 14. Løsningsforslag - prøveeksamen. Institutt for Informatikk Fredrik Sørensen og Arne Maus

Oppgave 2 (20 poeng) float og long i oppgave 2:

Tre måter å lese fra terminal. Java 4. Eksempel. Formatert utskrift til skjerm

INF1000 (Uke 15) Eksamen V 04

INF1000 (Uke 15) Eksamen V 04

INF1010 Arv. Marit Nybakken 2. februar 2004

INF1000 (Uke 4) Mer om forgreninger, While-løkker

UNIVERSITETET I OSLO

INF1000 undervisningen INF 1000 høsten 2011 Uke september

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

Feilmeldinger, brukerinput og kontrollflyt

Hittil har programmene kommunisert med omverden via tastatur og skjerm Ønskelig at data kan leve fra en kjøring til neste

Inf1010 oppgavesamling

Ukeoppgaver INF1000: 12. feb 16. feb

INF1000-SIKT - Notat om I/O i Java

Tilstandsmaskiner med UML og Java

UNIVERSITETET I OSLO

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

Transkript:

J INF1010 Tråder J Marit Nybakken marnybak@ifi.uio.no Motivasjon Til nå har vi kun skrevet programmer der programmet bare var på ett sted i koden til enhver tid (bortsett fra når vi har drevet med GUI, men der skjønte vi liksom ikke helt hva som skjedde). Men nå skal vi slippe ulven løs og begynne å lage programmer der programmet kan kjøre på flere steder i koden samtidig. Dette kan brukes til å utnytte ressursene i maskinen bedre Hvis maskinen har flere prosessorer kan en tråd kjøre på hver prosessor Hvis en tråd venter på lesing fra f.eks. tastatur eller disk, kan den andre tråden bruke CPUen. simulere situasjoner der flere oppgaver faktisk utføres samtidig Vi vil da gjerne skrive forskjellige klasser for de forskjellige oppgavene og kjøre en tråd i hver klasse. Dette fører til krangling og krig mellom trådene. Din oppgave som programmerer er nå å være megler mellom trådene og se til at alt går riktig for seg. Illustration 1Tråder er ikke lett å holde styr på Å lage en tråd Vi kan legge til en ny tråd i programmet vårt ved å lage en ny klasse som arver fra klassen Thread class MinTråd extends Thread {

// Her skal vi legge all koden som tråden // skal utføre for(int i=0;i<15;i++) System.out.println(""); Klassen skal ha en metode public void run(). I denne legger vi koden som tråden skal kjøre (den kan selvfølgelig kalle andre metoder også). For å starte tråden lager vi så et objekt av denne klassen. Deretter kaller vi metoden start() i objektet. Denne kaller så på run()- metoden igjen. Vi kaller aldri run-metoden direkte: class LageEnTråd { public static void main(string [] args) { // Lager en tråd MinTråd t = new MinTråd(); // Starter opp tråden t.start(); for(int i=0;i<15;i++) { System.out.println(""); Nå vil utskriften fra main og fra tråden komme hulter til bulter på skjermen. Først får main skrive ut litt, deretter får den nye tråden skrive ut litt, så main igjen. Vi sier at de kjører samtidig, men egentlig byttes det raskt mellom de to trådene:

Å pause en tråd Vi kan få en tråd til å ta en pause ved å kalle på sleep(sovetid_i_ms). Sleep kan kaste et unntak, InterruptedException, og dette må vi fange opp med try-catch (mer om unntak i kap 19). Det gjøres slik: class MinTråd extends Thread { // Pause tråden i 5 sekunder int tid_å_sove = 5000; // 5000 ms = 5 sek try { sleep(tid_å_sove); catch(interruptedexception e) { // Her legges koden som skal kjøres etter tråden // starter igjen En tråd vil også pause når den venter på input fra tastatur, akkurat som programmer vanligvis gjør (står og henger til vi skriver inn noe). Dette betyr dog ikke at alle de andre trådene også står og venter selv om en tråd har skrevet tast.inint(), og dette kan føre til forvirring for brukeren. Å stoppe en tråd Det er usannsynlig enkelt å stoppe en tråd. En tråd stopper rett og slett når den er ferdig med runmetoden sin. Kommunikasjon mellom trådene Når trådene kun jobber på sine egne data er det vanligvis ikke noe problem å bruke dem. Det er bare å kjøre dem i gang og la dem drive med sitt. Det virkelige problemet med trådene starter først når de skal

begynne å jobbe med data som de alle deler på. Her er en klasse med data som kan deles for to tråder (bare som et teit eksempel). Det kunne like gjerne vært data i et objekt av en klasse. class Delt { // Delte data static int [] liste = new int [100]; static int ant = 0; En trådklasse som bruker de delte dataene. Den legger en verdi inn i arrayen til vi har kommet til slutten av arrayen (indeks > 99). class Tråddings extends Thread { int verdi = 0; while(delt.ant < 100) { // Er du helt sikker på at Delt.ant fremdeles // er mindre enn 100? Delt.liste[Delt.ant] = verdi; // endre delte data Delt.ant++; verdi++; Så oppretter vi to tråder og setter dem i gang class DummeTråder { public static void main(string [] args) { // Lager to tråder Tråddings t1 = new Tråddings(); t1.start(); Tråddings t2 = new Tråddings(); t2.start(); De første gangene vi kjører det, går alt fint. Så... D:\komp\tråder>java DummeTråder D:\komp\tråder>java DummeTråder D:\komp\tråder>java DummeTråder D:\komp\tråder>java DummeTråder

java.lang.arrayindexoutofboundsexception: 100 at Tråddings.run(LageTråd.java:24) Hva skjedde her? Delt.ant er 99. Tråd 1: while(99 < 100) { Tråd 1 er inne i løkken. Så får tråd 2 kjøre: Tråd 2 : while(99 < 100) { Delt.liste[99] = verdi; Delt.ant = 100; Så får tråd 1 kjøre igjen. Tråd 1: Delt.liste[Delt.ant] = verdi; Men Delt.ant er nå 100! Derfor kræsjer programmet, vi har gått utenfor arrayen. synchronized, pass på dataene dine En slik situasjon kalles for en race condition. Resultatet avhenger av hvilken tråd som kommer først. Kode der tråder opererer på delte data kalles kritisk kode. Slik kode må beskyttes slik at kun en tråd kan kjøre den av gangen. Det siste kalles gjensidig utestengelse, når en tråd er inne i koden stenges alle andre tråder ute. Illustration 2race condition - førstemann til mølla I java har alle objekter noe som kalles for monitorer og som kan passe på at bare en tråd får lov til å kjøre kode i objektet til envher tid. Det funker slik at man setter synchronized foran metoder i objektet som inneholder kritisk kode. class Delt { static int [] liste = new int [100]; static int ant = 0;

synchronized static void delt(int verdi, int pos) { liste[pos] = verdi; Man kan også lage synchronized-blokker, slik: synchronized { <farlig kode> Illustration 3Bare en slipper innenfor synchronized av gangen, og tar samtidig monitoren Monitorer er dørvakter til de synkroniserte metodene. I det en tråd går inn i en synkronisert metode, støter den på monitoren. Er det ledig i metoden, slipper tråden inn. Hvis det er noen inni metoden fra før av, blir tråden pauset og satt på monitorens venteliste. Når tråden som er i metoden er ferdig vil monitoren la den første på ventelista få slippe inn. Vent på turen din

Tråder som er høflige nok kan også samarbeide om å synkronisere seg ved hjelp av monitoren. En tråd som finner ut at den ikke har noe å gjøre for tiden kan sette seg selv på monitorens venteliste ved å kalle på wait() i en synkronisert metode. Da slipper den samtidig monitoren. Dermed slipper andre tråder til i de synkroniserte metodene. Når de er ferdig med sitt arbeid, kan de vekke tråden opp igjen når det er tid for at den skal jobbe ved å kalle notify(). Dette vekker opp første tråd på lista, som så kan inspisere og se om det er noe å gjøre. Den får dog ikke lov til å gjøre noe som helst før monitoren er sluppet av den andre tråden. Det finnes også et notifyall()-kall, som vekker alle tråder på ventelista. Wait og notify bruker vi gjerne i produsent-konsument-programmer. Altså der vi har en tråd som produserer data og en som bruker (konsumerer) disse dataene. Konsumenten kan ikke konsumere før produsenten har produsert, og produsenten kan ikke produsere nye data før konsumenten har brukt de gamle. Her er et eksempel på dette: class Delt { // Delte data double [] liste = new double [10]; // Skal være true når listen er utskrevet og klar for å fylles // og false når listen er fyllt og klar for å bli utskrevet boolean listeutskrevet = true; // Skriv ut innholdet av listen (konsumentens metode) synchronized void skrivut() { // Vent til det er noe å skrive ut while(listeutskrevet) { try { wait(); catch(interruptedexception e) { // Skriv ut for(int i=0;i<liste.length;i++) System.out.println(liste[i]); // Si i fra at listen er klar til å fylles listeutskrevet = true; notify(); // Fyll listen med data (Produsentens metode) synchronized void fyllliste(int val) { // Vent til listen er ferdigskrevet while(!listeutskrevet) { try {

wait(); catch(interruptedexception e) { // Fyll listen med noe junk for(int i=0;i<liste.length;i++) { liste[i] = Math.cos((double)i/val); // Si fra at listen er klar til utskrift listeutskrevet = false; notify(); class Produsent extends Thread { Delt d; Produsent(Delt d) { this.d = d; for(int i=0;i<10;i++) d.fyllliste((i+1)); class Konsument extends Thread { Delt d; Konsument(Delt d) { this.d = d; for(int i=0;i<10;i++) d.skrivut(); Den ene tråden fyller listen, den andre skriver ut. Men før de gjør dette, sjekker de, ved hjelp av listeutskrevet-variabelen, hvorvidt dette skal gjøres nå eller ikke. Hvis listen ikke er fylt, setter konsumenten seg til å vente. Hvis listen er fylt, setter produsenten seg til å vente. De vekkes opp ved hjelp av notify() når tilstanden på listen er endret. Klassen som oppretter trådene: class Samarbeid {

public static void main(string [] args) { Delt d = new Delt(); Produsent p = new Produsent(d); Konsument k = new Konsument(d); p.start(); k.start(); Illustration 4Livet til en tråd