170 likes | 422 Views
Tråder. Hva er en tråd? side 2-4 Deling av tid mellom tråder side 5-6 Tråder med Runnable side 7 Trådenes tilstander side 8 Kommunikasjon mellom tråder side 9-10 Låser og synkronisering side 11-12 wait(), notify() og notifyAll() side 13 Avbrudd side 14-17. Hva er en tråd?.
E N D
Tråder Hva er en tråd? side 2-4Deling av tid mellom tråder side 5-6Tråder med Runnable side 7Trådenes tilstander side 8Kommunikasjon mellom tråder side 9-10Låser og synkronisering side 11-12wait(), notify() og notifyAll() side 13Avbrudd side 14-17 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Hva er en tråd? • Når vi starter et program, kan vi også si at vi starter en prosess. • Flere prosesser (program) kan kjøre tilsynelatende samtidig (multitasking), eksempler: tekstbehandler og regneark og vårt eget Java-program. • Også innenfor et og samme program kan flere operasjoner kjøre tilsynelatende samtidig, for eksempel skriving til disk og kompliserte beregninger. Slike (små) prosesser inne i prosesser kalles tråder. • På datamaskiner med én prosessor fordeler operativsystemet prosessortiden mellom prosessene/trådene som tilsynelatende kjører samtidig. • Bytte av prosess/tråd kalles kontekstbytte. • Dataene som tilhører en prosess lagres unna ved kontekstbytte, og de hentes fram igjen neste gang det er denne prosessen sin tur til å kjøre. • Tråder kjører inne i andre prosesser, og tråder i en og samme prosess har ofte felles data som det ikke er nødvendig å lagre unna. Tråder kalles derfor også lettvektsprosesser. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Prosesser og tråder prosess 1 prosess 3 prosess 2 tråd 1 tråd 3 tråd 1 tråd 2 tråd 1 tråd 2 Hver prosess får sin egen Process ID (PID) Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Kjøring av to tråder tråd 1 initiering tråd 2 fork-linje en operasjon gjør parallell operasjon avventer resultat fra tråd 2 join-linje nye operasjoner Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Deling av tid mellom tråder • To ulike måter å dele tiden mellom tråder på: • Tråden sier selv fra at den kan ta en pause. • En mekanisme utenfor tråden legger tråden i dvale med makt. (”preemptive multitasking”) Mekanismen ligger i Java-tolkeren, eller i operativsystemet. • Mekanismen for å dele tiden er plattformavhengig. • Nyere Java-tolkere benytter som oftest metode 2. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Eksempel class Tallskriver extends Thread { private int tallSomSkrives; public Tallskriver(int tall) { tallSomSkrives = tall; } public void run() { while (true) { System.out.print(tallSomSkrives); System.out.print(" "); } } } class Tallskur { public static void main(String[] args) { Tallskriver skriver1 = new Tallskriver(1); Tallskriver skriver2 = new Tallskriver(2); Tallskriver skriver3 = new Tallskriver(3); Tallskriver skriver4 = new Tallskriver(4); Tallskriver skriver5 = new Tallskriver(5); skriver1.start(); skriver2.start(); skriver3.start(); skriver4.start(); skriver5.start(); } } Utskrift: • ... • 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 4 1 2 5 4 1 2 5 4 1 2 5 4 1 2 5 4 1 2 5 4 1 2 41 2 41 2 41 2 41 2 41 2 41 2 41 2 412 5 12 5 12 5 12 5 12 5 12 5 12 5 12 5 12 5 12 5 12 5 12 5 12 5 12 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 ... Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Konstruktøren til Thread kan ta et objekt som argument. Da benyttes dette objektets run()-metode. Objektet må tilhøre en klasse som implementerer Runnable. Hensiktsmessig dersom vår trådklasse skal være subklasse til en annen klasse enn Thread class Superklasse { } class Traaden extends Superklasse implements Runnable { private Thread traad; public Traaden() { traad = new Thread(this); traad.start(); } public void run() { while (true) { System.out.println("Lever..."); } } } class VaarTraad { public static void main(String[] args) { Traaden tr = new Traaden(); } } Tråder med Runnable Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Trådenes tilstander • New • Før og mens start() starter. • Runnable • Når run() kjører. Også når tråden midlertidig er stoppet på grunn av at en annen tråd er tildelt kjøretid. • Blocked • Når tråden gir seg selv en pause med sleep() eller wait(). • Når den venter på IO. • Dead • Når run() har avsluttet av seg selv. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Kommunikasjon mellom tråder • En tråd bør generelt tenke på at andre bør få slippe til av og til. • Samtidig bør antall kontekstbytter ikke være flere enn nødvendig. • static void sleep(long millisekunder) • Klassemetode som sender aktuell tråd inn i hviletilstand den oppgitte tiden, kan for eksempel brukes til å justere farten på en animasjon. • static void yeld() • Klassemetode som sier at aktuell tråd kan ta en pause dersom andre venter på å slippe til. • Spesielt aktuelt å bruke denne metoden dersom vi ikke kan være sikre på at plattformen vi kjører på har preemptive multitasking. • void join() • Tråd A sender meldingen join() til tråd B. Da vil A stoppe opp inntil tråd B dør. • void join(long millisekunder) • Nå vil tråden som sender meldingen (tråd A) vente maksimalt den oppgitte tiden. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Join mellom tråder tråd 1 tråd 2 tråden gjør seg ferdig tråden vil “joine” med tråd 2, og sender meldingen join() tråd 1 fortsetter, join() returnerte i det tråd 2 avsluttet Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Låser og synkronisering • Alle trådene i et program har tilgang til programmets objekter og klasser tilnærmet samtidig. • Hva hvis flere tråder jobber med oppdatering av det samme objektet tilnærmet samtidig? • En tråd kan gjerne bli stoppet midt i en metode. tråd 2 tråd 3 metodekall metodekall tråd 1 skrivSekvens(); metodekall objekt som trådene benytter Vis programliste 16.3 side 594-595 med resultatutskrift Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Løsningen: synchronized public synchronized void skrivSekvens() { System.out.print("1 "); System.out.print("2 "); System.out.print("3 "); System.out.print("4 "); System.out.print("5 "); } • synchronized sikrer oss ikke mot at metoden avbrytes ved kontekstbytte, men at en annen tråd starter den på ny, eller starter en annen av objektets synkroniserte metoder. • En tråd son kjører en synkronisert metode, tar objektets lås, den låser alt som er synkronisert i objektet for andre tråder. • synchronized sinker programutførelsen noe. Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
wait(), notify() og notifyAll() • Anta at en tråd er inne i en synkronisert del av et objekt. • Dersom andre trenger å slippe til, må tråden gi fra seg låsen: • void wait() • void wait(long millisekunder) • Tråden som venter, er nå i tilstanden Blocked • Tråden må vekkes opp ved at en annen tråd sender melding til objektet: • void notify() • vekker en enkelt tråd som venter • void notifyAll() • vekker alle trådene som venter Vis programliste 16.4 side 598-600 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Avbrudd • En tråd kan bli hengende lenge på grunn av metodekallene wait(), sleep() og join() • Kan avbryte dette ved å sende meldingen interrupt() til tråden. • Et flagg heises (jmf. logisk variabel settes true) som forteller at tråden er havnet i en undertilstand, den er ”avbrutt” (interrupted). • Dersom tråden venter • unntaket InterruptedException kastes • avbruddsflagget fires • håndteringen av dette unntaket forteller hva som deretter skal skje • Dersom tråden ikke venter • unntak kastes ikke • må sjekke om den er blitt avbrutt • if (isInterrupted())…..kanskje avslutte?… • eventuelt også fire avbruddsflagget • static boolean interrupted() // obs! klassemetode Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Eksempel, isInterrupted() og interrupted()Eksemplet er hentet fra Chan, Lee & Douglas: The Java Class Libraries, sec.ed. Vol. I, , Addison-Wesley 1998, ISBN 0-201-31002-3, pp. 1733-1734. • Klassene Sleeper og Counter er vist på de neste sidene. • Hovedprogrammet er det samme: import java.util.Random; class MainSleeper { public static void main(String[] args) { Thread t = new Sleeper(); // bytt ut denne med Counter i eksempel 2 t.start(); Random rand = new Random(); while (true) { int p = Math.abs(rand.nextInt()%5000); System.out.println("wake up worker in " + p + "ms"); try { Thread.sleep(p); // hovedtråden sover,… } catch (InterruptedException e) { System.out.println("main interrupted"); } t.interrupt(); // … og vekker deretter opp den andre tråden } } } Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Eksempel Sleeper alltid false på grunn av at InterruptedException er kastet class Sleeper extends Thread { public void run() { while (true) { try { Thread.sleep(2000); System.out.println("sleeper woke up"); } catch (InterruptedException e) { System.out.println("sleeper interrupted (1): " + isInterrupted()); System.out.println("sleeper interrupted"); } System.out.println("sleeper interrupted (2): " + isInterrupted()); } } } alltid false på grunn av at programkontrollen kommer hit uten å bli avbrutt, enten via unntakshåndteringen eller utenom denne fordi 2000 ms har gått Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.
Eksempel Counter class Counter extends Thread { public void run() { while (true) { long sum = 0; // antall løkkegjennomløp justeres etter hastigheten på maskinen, // kjøring skal gi en og annen true verdi i utskriften for (int i = 0; i< 1000000 && !isInterrupted(); i++) { sum += i; } System.out.println("Sum: " + sum); System.out.println("isInterrupted (0): " + isInterrupted()); System.out.println("isInterrupted (1): " + isInterrupted()); System.out.println("interrupted(0): " + Thread.interrupted()); // First call should have cleared it. System.out.println("interrupted (1): " + Thread.interrupted()); } }} true dersom avbrudd før summeringen er ferdig alltid false på grunn av at interrupted() firer avbruddsflagget Les kapittel 16.8 og gjør oppgaven side 603 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik og Vegard B. Havdal, 3.utgave, Stiftelsen TISIP og Gyldendal Akademisk 2004.