• No results found

Objectorienterad programmering Sida 5 Trådar Sven-Olof Nyström javax.swing.Timer: Exempel public class Hej implements ActionListener { public Hej

N/A
N/A
Protected

Academic year: 2021

Share "Objectorienterad programmering Sida 5 Trådar Sven-Olof Nyström javax.swing.Timer: Exempel public class Hej implements ActionListener { public Hej"

Copied!
11
0
0

Loading.... (view fulltext now)

Full text

(1)

Trådar

Sven-Olof Nyström Uppsala Universitet

20 april 2006

Objectorienterad programmering Sida 1

Trådar Sven-Olof Nyström

Dagens ämnen

Timers

Trådar

Synkronisering

Buffrad kommunikation

Producent/Konsument-exempel

Motivering

Många program måste kunna hålla på med flera saker samtidigt, till exempel

fleranvändarsystem

en webserver som måste kunna leverera flera websidor samtidigt

ett grafiskt system som ritar samtidigt som det arbetar med nästa bild

ett system som reagerar på input samtidigt som det utför en beräkning

Objectorienterad programmering Sida 3

Trådar Sven-Olof Nyström

Hålla på med flera saker...

en browser som kan börja visa dokumentet innan hela dokumentet är nerladdat

ett program som kontrollerar olika delar av en maskin

ett program som övervakar olika delar av ett system Det är inte nödvändigt att använda trådar, men ofta lättare.

(2)

Aktiva objekt

Aktiva objekt: objekt som själva kan initera skeenden.

I Java finns det två sätt att beskriva aktiva objekt;

javax.swing.Timer kan användas för att kontrollera en grupp av aktiva objekt, om de bara behöver arbeta i korta moment. (Det finns även en liknande klass, java.util.Timer.)

med hjälp av trådar java.lang.Thread kan man hantera objekt som arbetar i längre moment (eller kontinuerligt).

Objectorienterad programmering Sida 5

Trådar Sven-Olof Nyström

javax.swing.Timer: Exempel

public class Hej implements ActionListener { public Hej () {

javax.swing.Timer tim = new javax.swing.Timer(1000, this);

tim.start();

}

public void actionPerformed (ActionEvent e) { System.out.println("Hej");

}

public static void main (String [] arg) { Hej h = new Hej();

for (int i = 0; i<Integer.MAX_VALUE; i++) {}

}}

Enkelt exempel–testkörning

svenolof@hamberg$ svenolof@hamberg$ javac Hej.java svenolof@hamberg$ java -Djava.compiler=NONE Hej Hej

Hej Hej Hej Hej Hej

^C

Objectorienterad programmering Sida 7

Trådar Sven-Olof Nyström

new Timer(m, l) Skapa en timer som genererar en händelse var mte millisekund, med l som lyssnare.

start() Starta timern.

stop() Stanna timern.

restart() Återstarta.

setDelay() Ändra intervallet mellan händelser.

setRepeats(false) Bara en händelse genereras.

(3)

Digitalklocka (från Skansholm)

public class DigitalKlocka extends JLabel implements ActionListener {

private DateFormat df = DateFormat.getTimeInstance();

public DigitalKlocka () {

setHorizontalAlignment(JLabel.CENTER);

setOpaque (true);

setBackground(Color.white);

setFont(new Font("SansSerif", Font.BOLD, 24));

javax.swing.Timer tim =

new javax.swing.Timer(1000, this);

tim.start();

}

Objectorienterad programmering Sida 9

Trådar Sven-Olof Nyström

public DigitalKlocka(String zon) { this();

df.setTimeZone(TimeZone.getTimeZone(zon));

}

public void actionPerformed(ActionEvent e) { setText (df.format (new Date()));

} }

public class KlockDemo extends JFrame { private DigitalKlocka k1 = new DigitalKlocka();

private DigitalKlocka k2 = new DigitalKlocka("EST");

public static void main(String[] args) { KlockDemo kd = new KlockDemo();

}

Objectorienterad programmering Sida 11

Trådar Sven-Olof Nyström

public KlockDemo () {

Container c = getContentPane();

JLabel l1 = new JLabel("Lokal tid", JLabel.CENTER);

JLabel l2 = new JLabel("New York", JLabel.CENTER);

l1.setFont(new Font("Serif", Font.BOLD, 18));

l2.setFont(new Font("Serif", Font.BOLD, 18));

c.setLayout(new GridLayout(2,2,5,5));

c.add(k1); c.add(k2); c.add(l1); c.add(l2);

setSize(500, 250);

setVisible(true);

setDefaultCloseOperation(EXIT_ON_CLOSE);

} }

(4)

Trådar

Vad är en tråd?

En ensam tråd liknar ett ‘vanligt’ sekvensiellt program

men när vi har flera trådar blir det intressant.

Exempel: HotJava, en web-browser

man kan scrolla en sida medan den laddar ner nånting stort

I verkligheten kan flera saker pågå samtidigt, så varför inte i en dator?

Objectorienterad programmering Sida 13

Trådar Sven-Olof Nyström

I alla moderna operativsystem finns processer och trådar

Processer är dyra,

har eget minnesskydd

används om flera användare kör samtidigt...

...eller om en användare kör flera program

om en process kraschar ska andra processer inte påverkas

Trådar och processer Trådar...

är billigare

används om man vill låta en applikation hålla på med flera saker samtidigt.

Ibland används begreppet lättviktsprocess. Det är samma sak.

Implementationer av Java brukar använda operativsystemets trådar.

Objectorienterad programmering Sida 15

Trådar Sven-Olof Nyström

Schemaläggning (scheduling)

Cooperative scheduling

Tråden körs tills den frivilligt ger upp kontrollen.

Preemptive scheduling

Byte mellan trådar sker automatiskt.

Äldre versioner av Windows använder cooperatice scheduling

Moderna OS använder preemptive scheduling

(5)

Trådar. Ett enkelt exempel

class SimpleThread extends Thread { public SimpleThread(String str) {

super(str); } public void run() {

for (int i = 0; i < 10; i++) {

System.out.println(i + " " + getName());

try {

sleep((long)(Math.random() * 1000));

} catch (InterruptedException e) {}

}

System.out.println("DONE! " + getName());

}}

Objectorienterad programmering Sida 17

Trådar Sven-Olof Nyström

public class TwoThreadsDemo {

public static void main (String[] args) { new SimpleThread("Jamaica").start();

new SimpleThread("Fiji").start();

} }

svenolof@harpo$ svenolof@harpo$ javac TwoThreadsDemo.java svenolof@harpo$ java TwoThreadsDemo

0 Jamaica 0 Fiji 1 Fiji 2 Fiji 1 Jamaica 2 Jamaica 3 Jamaica [...]

7 Jamaica 9 Fiji 8 Jamaica 9 Jamaica DONE! Fiji DONE! Jamaica svenolof@harpo$

Objectorienterad programmering Sida 19

Trådar Sven-Olof Nyström

Java.lang.thread

Viktiga metoder

start() Börja exekvering av nyskapad tråd

sleep() Avbryt exekvering av tråd. Under den angivna tiden ‘sover’ tråden

yield() Ge en annan tråd möjlighet att köra

Exempel: Primes.java—En tråd beräknar primtal, en annan skriver ut det senast beräknade.

(6)

Alternativt sätt att skapa och köra trådar

I stället för att från klassen Thread,

låt klassen K implementera interfacet Runnable

En metod: run()

K k = new K();

Thread t = new Thread(k);

t.start();

Objectorienterad programmering Sida 21

Trådar Sven-Olof Nyström

Synkronisering

Exempel: En enkel klass Konto:

class Konto { private int saldo;

..

public void transaktion( int belopp ) { saldo = saldo + belopp;

} ..

}

Synkronisering (forts)

Ett scenario med trådarna bankomat och girering.

1. Tråden bankomat anropar transaktion och har just beräknat saldo+belopp när den avbryts.

2. Tråden girering anropar transaktion, lägger till en summa och hinner ändra saldo

3. Tråden bankomat väcks och ger saldo “sitt” värde (ursprungligt saldo minus det uttagna beloppet).

Objectorienterad programmering Sida 23

Trådar Sven-Olof Nyström

Synkronisering (forts) Efter dessa “transaktioner”:

Saldot har minskat med det uttagna beloppet

De insatta pengarna är borta (eftersom tråden girering var snabbare än tråden bankomat).

För att eliminera risken att sådant här ska hända kan man deklarera metoder synchronized (som låser objektet)

Metoden transaction skulle alltså deklareras synchronized public void transaktion(int belopp) {

(7)

Hur kommunicerar två trådar?

Enkel lösning: Ett objekt som båda kan se och uppdatera.

Men hur upptäcker en process att ett objekt har uppdaterats?

I klassen Object finns de tre metoderna

wait() — vänta till någon blir väckt, öppna låset

notify() — väck en väntande tråd

notifyAll() — väck alla väntande trådar

Objectorienterad programmering Sida 25

Trådar Sven-Olof Nyström

public class CubbyHole <T>{

private T contents;

private boolean available = false;

public synchronized T get() { while (available == false) {

try { wait();

} catch (InterruptedException e) { } }

available = false;

notifyAll();

return contents;}}

public synchronized void put(T value) { while (available == true) {

try { wait();

} catch (InterruptedException e) { } }

contents = value;

available = true;

notifyAll();

} }

Objectorienterad programmering Sida 27

Trådar Sven-Olof Nyström

Producer

public class Producer extends Thread { private CubbyHole<Integer> cubbyhole;

private int number;

public Producer(CubbyHole<Integer> c, int number) { cubbyhole = c;

this.number = number;

}

(8)

Producer (forts)

public void run() {

for (int i = 0; i < 10; i++) {

cubbyhole.put(i + this.number*10);

System.out.println("Producer #" + this.number + " put: " + (i + this.number*10));

try {

sleep((int)(Math.random() * 100));

} catch (InterruptedException e) { } }

} }

Objectorienterad programmering Sida 29

Trådar Sven-Olof Nyström

Consumer

public class Consumer extends Thread { private CubbyHole<Integer> cubbyhole;

private int number;

public Consumer(CubbyHole<Integer> c, int number) { cubbyhole = c;

this.number = number;

}

Consumer (forts)

public void run() { int value = 0;

for (int i = 0; i < 10; i++) { value = cubbyhole.get();

System.out.println("Consumer #" + this.number + " got: " + value);

try {

sleep((int)(Math.random() * 50));

} catch (InterruptedException e) { } }}}

Objectorienterad programmering Sida 31

Trådar Sven-Olof Nyström

ProducerConsumerTest

public class ProducerConsumerTest { public static void main(String[] args) {

CubbyHole<Integer> c = new CubbyHole<Integer>();

Producer p1 = new Producer(c, 1);

Producer p2 = new Producer(c, 2);

Producer p3 = new Producer(c, 3);

Consumer c1 = new Consumer(c, 1);

Consumer c2 = new Consumer(c, 2);

p1.start();

p2.start();

p3.start();

c1.start();

c2.start();

} }

(9)

Cubbyhole: testkörning

svenolof@harpo$ java5 ProducerConsumerTest Consumer #2 got: 10

Producer #3 put: 30 Consumer #1 got: 20 Producer #2 put: 20 Producer #1 put: 10 Consumer #1 got: 30 Producer #3 put: 31 Consumer #2 got: 21 Producer #2 put: 21 Consumer #1 got: 31 Producer #3 put: 32 Consumer #2 got: 32 Producer #1 put: 11 Consumer #1 got: 11 Producer #3 put: 33 Consumer #2 got: 33 Producer #2 put: 22 Consumer #1 got: 22 Producer #3 put: 34 Consumer #2 got: 34 Producer #1 put: 12 [...]

Objectorienterad programmering Sida 33

Trådar Sven-Olof Nyström

Producer2: Använd Runnable

class Producer2 implements Runnable { [...]

private Thread t = null;

public Producer2(CubbyHole<Integer> c, int number) { [...]

this.t = new Thread(this);

}

public void start() { t.start();

}

public void run() {...}}

Köer

Ett gränssnitt: BlockingQueue

Implementerande klasser LinkedBlockingQueue och ArrayBlockingQueue

LBQ är obegränsad;

ABQ har en maxstorlek (som anges i konstruktorn)

Objectorienterad programmering Sida 35

Trådar Sven-Olof Nyström

Köer, metoder

void put(e) Sätt in e sist i kön

<T>take() ta ut första elementet

<T>poll() första elementet om det finns, annars null

<T>poll(n,u) med timeout

Producer-consumer exempel, med BlockingQueue

(10)

Trådar, fler exempel

PipeTest.java—Kommunikation med en ström.

Objectorienterad programmering Sida 37

Trådar Sven-Olof Nyström

Problem med trådar

Java använder normalt operativsystemets trådar.

Tyvärr slår skillnader mellan olika OS igenom i beteendet hos olika trådade program. Detta innebär att man inte alltid kan flytta trådade program mellan maskiner.

Om man glömmer att synkronisera kan man få problem med tidsberoenden (race conditions).

Om man synkroniserar för mycket kan programmet hänga sig, till exempel om två processer har låst varsitt objekt som den andra processen behöver (deadlock).

Problem med trådar (forts)

Synkronisering är en ganska dyr operation.

Trådar är en knapp resurs—en modern dator klarar några tusen.

Att programmera med nära samverkande trådar är krångligt pga oförutsägbarhet i schedulering etc.

Objectorienterad programmering Sida 39

Trådar Sven-Olof Nyström

Trådar: Några råd

Låt multitrådade program följa enkla modeller, till exempel med buffrad kommunikation eller som den multitrådade servern i nästa föreläsning.

Undvik situationer där många trådar läser och skriver samma objekt.

Låt inte antalet trådar växa obegränsat.

(11)

Sammanfattning

Två sätt att programmera aktiva objekt.

Timers—relativt enkelt men inte så kraftfullt.

Trådar—kraftfullare men det finns många fallgropar.

Objectorienterad programmering Sida 41

References

Related documents

Vi finns från norr till söder och har du frågor eller funderingar kring de gröna näringarna så tveka inte att kontakta oss eller gå in på vår hemsida och läs

En funktion kan vara av typen void som anger att den inte returnerar något värde. 26-Feb-2006

• Swing ingår som en del av AWTs klasshierarki: alla klasser i Swing ärver från AWT-klassen Container. • Klasser i Swing har ett namn som börjar

• Alla andra undantag tillhör gruppen Checked Exception..

I dag sitter i alla de nordiska parlamenten människor från partier som vunnit röster för att de gjort politik av misstro mot samhälls- och kultureliten, eller för att de

Om man går till underliggande behov finns många fler möjligheter till lösningar än om man bara säger vad man vill, eller värre, kräver att få sin vilja igenom.. Ett annat

Skickat: den 30 mars 2012 17:24 Till: Olof Junesjö Kommunkontoret Ämne: Workshop.

Vidare har vi även identifierat målgruppen, målgruppens attityder till hälsningar, på vilka platser hälsningar är mer och mindre troliga att ske, och även fria svar