Proz S6

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 1

6. W

ą

tki



6.1 Poj

ę

cie w

ą

tku programu

6.2 Klasy

Timer

,

TimerTask

6.3 Klasa

Thread

6.4 Synchronizacja pracy w

ą

tków

6.5 Grupowanie w

ą

tków



6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 2

6.1 W

ą

tki programu

1) Poj

ę

cie w

ą

tku

W

ą

tek ("thread")

to osobna sekwencja wykonania instrukcji programu

w ramach jednego programu, wykonywana

współbie

ż

nie

z innymi

w

ą

tkami tego programu.

W odró

ż

nieniu od procesu w

ą

tek posiada jedynie swój

kontekst

wykonania – stos, rejestry i licznik rozkazów

– ale współdzieli on

pami

ęć

dynamiczn

ą

(„stert

ę

”) programu z innymi w

ą

tkami tego

programu.
W

ą

tki znajduj

ą

zastosowanie tam, gdzie rozwi

ą

zanie zadania mo

ż

e

by

ć

zrealizowane przez

algorytm równoległy

. Przykłady zada

ń

dla

w

ą

tków: obliczenie liczb pierwszych, sortowanie danych, wykonywanie

animacji, itp.
Dzi

ę

ki

w

ą

tkom

realizujemy

mechanizm

asynchronicznego

wywoływania i wykonywania metod w

ramach jednego programu.

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 3

6.2 Klasy

Timer

i

TimerTask

Klasy

java.util.Timer

(

extends Object

)

i

TimerTask

(extends Object

implements Runnable)

s

ą

po

ż

yteczne do wyznaczania czasu wznowienia

w

ą

tku po pewnej przerwie.

Uwaga: dla programu posiadaj

ą

cego GUI realizowany w

Swing

-u

odpowiedni

ą

klas

ą

jest

javax.swing.Timer

zamiast

java.util.Timer

.

Metody klasy

Timer

przeznaczone do

wybierania zada

ń

:

// Wykonanie zadania po upływie czasu lub o dokładnej porze:

schedule (TimerTask task, long delay)

schedule (TimerTask task, Date time)

// Wielokrotne wznawianie wykonania co okres czasu:
// - "mi

ę

kkie" dotrzymanie okresu – gdy poprzednie wykonanie si

ę

zako

ń

czyło

schedule (TimerTask task, long delay, long okres)

schedule (TimerTask task, Date time, long okres)

//- ustalony na sztywno okres –bez wzgl

ę

du na zako

ń

czenie poprzedniego

scheduleAtFixedRate (TimerTask task, long delay, long okres)

scheduleAtFixedRate (TimerTask task, Date firstTime, long okres)

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 4

Jednokrotne asynchroniczne wykonanie zadania

po upływie czasu

Przykład.

Zastosujemy klasy

Timer

i

TimerTask

dla asynchronicznego

wykonania zadania po upływie 5 sekund.

import java.util.Timer;
import java.util.TimerTask;
public class Przypomnienie

{

// Klasa główna naszego zadania

Timer timer;
public Przypomnienie(int sekundy) {

// Konstruktor klasy głównej

timer = new Timer();

// (3) Tworzymy w

ą

tek - obiekt klasy

Timer

timer.schedule(new PrzypomTimerTask(), sekundy*1000);

// (4)

// (4) Tworzymy obiekt naszego typu pochodnego od

TimerTask

i

// wybieramy go do wykonania po upływie 5000 ms

}

// W klasie głównej definiujemy klas

ę

wewn

ę

trzn

ą

-

// (1) definiujemy własn

ą

klas

ę

pochodn

ą

po

TimerTask

:

class PrzypomTimerTask extends TimerTask {
public void run() {

// (2) Metoda

run()

wykonuje zadanie w

ą

tku

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 5

System.out.println("Czas minął!");
timer.cancel();

// Zako

ń

cz w

ą

tek – obiekt

timer

}
}
public static void main(String args[]) {

// Metoda main() klasy głównej

System.out.println("Wybieranie zadania.");
new Przypomnienie(5);

// Konstrukcja obiektu klasy głównej

System.out.println("Zadanie wybrane.");
}
}


Wynik:

Zadanie wybrane.

Czas minął

Drugi napis pojawi si

ę

po 5 sekundach po pierwszym.

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 6

Jednokrotne asynchroniczne wykonanie zadania

o okre

ś

lonej porze

Przykład.

Wykonanie zadania o godzinie 23:01. W tre

ś

ci konstruktora

naszej klasy

Przypomnienie

:

public Przypomnienie(int sekundy) {

// Pobierz dzisiejsz

ą

dat

ę

Calendar calendar = Calendar.getInstance();

calendar.set(Calendar.HOUR_OF_DAY, 23);

// Ustaw godzin

ę

calendar.set(Calendar.MINUTE, 1);
calendar.set(Calendar.SECOND, 0);
Date time = calendar.getTime();
timer = new Timer();

// Utwórz w

ą

tek nadzoruj

ą

cy czas

// Wykonaj w

ą

tek zadania o podanej godzinie tego dnia:

timer.schedule( new PrzypomTimerTask(), time);

}

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 7

Zatrzymanie w

ą

tków klasy Timer jest mo

ż

liwe na 4 sposoby:

1. wywołanie metody

cancel()

dla obiektu klasy

Timer

(jak powy

ż

ej);

2. utworzy

ć

w

ą

tek - „demon” wywołaniem konstruktora:

new Timer(true) ;

program którego jedynymi w

ą

tkami pozostały w

ą

tki demony zako

ń

czy

si

ę

(w podanych przykładach nie mo

ż

na tak post

ą

pi

ć

, gdy

ż

czekamy

na wykonanie si

ę

zadania zleconego przez obiekt klasy

Timer

);

3. usun

ąć

wszystkie

referencje

do obiektu klasy

Timer

, mo

ż

e to

zako

ń

czy

ć

w

ą

tek obiektu

Timer

-a.

4. wywołanie metody

System.exit

zako

ń

czy cały program - w tym jego

w

ą

tki.

Przykład.

Dodanie do klasy

Przypomnienie

dzwonka i wywołanie

metody

System.exit

w celu zako

ń

czenia programu.

public class PrzypomnienieDzwonkiem {

...

public PrzypomnienieDzwonkiem (int sekundy) {

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 8

toolkit = Toolkit.getDefaultToolkit();

// W celu uzyskania dzwonka

timer = new Timer();
timer.schedule(new PrzypomTimerTask(), sekundy*1000);

}

// Klasa dla zadania w

ą

tku

class PrzypomTimerTask extends TimerTask {
public void run() {

System.out.println(Czas minął!");
toolkit.beep();
//timer.cancel();

// Teraz niepotrzebne, gdyż wołamy System.exit

System.exit(0);

// Zatrzyma w

ą

tek główny programu (i inne)

}
} ...
}

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 9

Wielokrotne, cykliczne wykonywanie zadania

Przykład.

Wybieramy wykonanie zadania cyklicznie raz na sekund

ę

.

public class DenerwujacyDzwonek {
Toolkit toolkit;
Timer timer;
public DenerwujacyDzwonek () {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new PrzypomTimerTask(),

0,

// początkowe oczekiwanie

1*1000);

// cyklicznie co okres czasu 1 sekundy

}
class PrzypomTimerTask extends TimerTask {
int liczbaDzwonkow = 3;
public void run() {
if (liczbaDzwonkow != 0) {
toolkit.beep();

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 10

System.out.println("Dzwoni!");
liczbaDzwonkow--;
} else {
toolkit.beep();
System.out.println("Czas minął!");

//

timer.cancel();

//Niepotrzebne - wołamy System.exit

System.exit(0);

// Zatrzyma w

ą

tek główny (i inne)

}
}
}
...
}

Wynik wykonania

:

Zadanie wybrane.

Dzwoni!
Dzwoni! // 1 sekunda po 1-szym "Dzwoni"
Dzwoni! // 1 sekunda po 2-im "Dzwoni"
Czas minął! // 1 sekunda po 3-im "Dzwoni"

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 11

6.3 Klasa

Thread

Bazowa klasa w

ą

tków to

java.lang.Thread

- wprowadza m.in.

metody

:



start()

rozpoczyna wykonywanie tre

ś

ci w

ą

tku zdefiniowanej w

run()



stop(), stop(Throwable obj);

- (metody niezabezpieczone) zamiast

nich nale

ż

y sprawdza

ć

warunek w

run()

i zako

ń

czy

ć

odpowiednio t

ę

metod

ę

;



sleep(long millis), sleep(long millis, int nanos)

– u

ś

pienie w

ą

tku na

pewien czas;



yield()

czasowo zatrzymuje w

ą

tek i ustawia go na ko

ń

cu kolejki;



getPriority(), setPriority(int)

pobierze i ustawi priorytet w

ą

tku.

1) Metoda

run()

Implementacja

w

ą

tku

opartego

na

klasie

Thread

wymaga

zdefiniowania metody

void

run()

- zawera ona zadanie wykonywane

przez w

ą

tek. Klasa

Thread

zawiera definicj

ę

metody

run()

o

pustym

kodzie.

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 12

Klasy mog

ą

tworzy

ć

metody

run()

na

dwa sposoby

:

1. przez dziedziczenie po klasie

Thread

i nadpisanie metody

run()

;

2. przez implementacj

ę

interfejsu

Runnable

- wtedy klasa musi

zawiera

ć

implementacj

ę

metody

run()

.

Dziedziczenie po klasie

Thread

i nadpisanie

run()

- klasa

Thread

ju

ż

implementuje

Runnable

.

Przykład

.

Klasa

ProstyWatek

(implementuje

wątek)

i

klasa

DemoDwaWatki (wywołuje dwa wątki klasy ProstyWatek):

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

// Konstruktor klasy

super(str);

// To nada nazwę wątkowi

}
public void run() {

// Metoda run() zawiera zadanie wątku

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

// Wykonuje pętlę 10 razy

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

// Wyprowadza indeks

// iteracji i nazwę wątku

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 13

try {

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

// Uśpiony przez

// pewien czas – ale maksimum 1 sekundę.

} catch (InterruptedException e) {}
}
System.out.println("Wykonane! " + getName());

// Wyprowadza

// komunikat, w tym nazwę wątku.

}
}

// Klasa

DemoDwaWatki :

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

// Utwórz i uruchom w

ą

tek

new ProstyWatek ("Bahama").start();

// Utwórz i uruchom drugi w

ą

tek

new ProstyWatek ("Bermudy").start(); }
}

Wynik - na przemian wyprowadzane s

ą

wyniki kolejnych w

ą

tków:

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 14

0 Bahama
0 Bermudy
1 Bermudy
1 Bahama
2 Bahama
2 Bermudy
3 Bermudy
...
Wykonane! Bermudy
9 Bahama
Wykonane! Bahama

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 15

2) Implementacja interfejsu

Runnable

przez klas

ę

programisty

Przykład

. Aplet

Zegar

wy

ś

wietla

ć

b

ę

dzie aktualny czas i od

ś

wie

ż

a

ć

obraz co sekund

ę

- wykonuj

ą

c odpowiedni w

ą

tek. Klasa

Zegar

implementuje interfejs

Runnable

- w tym metod

ę

run()

.

import java.awt.Graphics;
import java.util.*;
import java.text.DateFormat;
import java.applet.Applet;
public class Zegar extends Applet implements Runnable {
private Thread watekZegara = null;

// Identyfikator dla obiektu wątku

public void start() {

// Metoda początkowa apletu

if (watekZegara

==

null) {

// Obiekt klasy Zegar przekaże siebie samego do konstruktora Thread –
// w ten sposób przekazana zostanie również implementacja metody
// run() właściwa dla klasy Zegar do obiektu klasy Thread.

watekZegara = new Thread(this, "Zegar");

//przekazanie do wątku

watekZegara.start();

// Uruchom wątek

.

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 16

}
}

// Zadanie w

ą

tku w metodzie

run()

public void run() {

Thread mojWatek = Thread.currentThread();
while
(watekZegara

==

mojWatek) {

repaint();

// Metoda apletu wołająca metodę paint()

try {
Thread.sleep
(1000);

// Samo-zawieszenie wykonywania wątku

} catch (InterruptedException e){

// Gdy JVM przerwie "nasz sen" zakończymy wykonywanie pętli.

}
}
}

// Nadpisanie metody

paint()

apletu

public void paint(Graphics g) {
Calendar cal = Calendar.getInstance();

// Pobierz dzisiejszą datę

Date date = cal.getTime();

// Pobierz czas, sformatuj go i wyświetl

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 17

DateFormat dateFormatter = DateFormat.getTimeInstance();
g.drawString(dateFormatter.format(date), 5, 10);
}

// Nadpisanie metody

stop()

klasy

Applet

, nie

Thread

public void stop() {

watekZegara = null;

//Zmienia warunek sprawdzany w metodzie run()

}
}

Uwagi



Dzi

ę

ki mechanizmowi w

ą

tków aplet

Zegar

nie blokuje wykonywania

si

ę

przegl

ą

darki.



Je

ś

li klasa ju

ż

dziedziczy po innej klasie ni

ż

Thread

(jak np.

Zegar

po

Applet

) to stosujemy 2-gie rozwi

ą

zanie - implementacj

ę

interfejsu

Runnable

.



W przeciwnym razie - stosujemy rozwi

ą

zanie 1-sze – dziedziczenie

naszej klasy po

Thread

.

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 18

3) "Cykl

ż

ycia" w

ą

tku

Nowo utworzony

Wykonywany

Zablokowany

Zako

ń

czony

Zako

ń

czenie metody run()

yield

start

Utworzenie w

ą

tku

Np. w metodzie

start()

apletu tworzony jest w

ą

tek o nazwie

watekZegara

:

public void start() {
if (watekZegara == null) {

watekZegara = new Thread(this, "Zegar");

watekZegara.start();

}

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 19

}

Po utworzeniu w

ą

tek

watekZegara

jest w stanie „

nowo utworzony

(„

new Thread

”)

- jest pustym obiektem klasy

Thread

bez zasobów

systemowych. Mo

ż

na go jedynie uruchomi

ć

- metod

ą

start()

(inne

odwołanie spowoduje powstanie wyj

ą

tku

IllegalThreadStateException

).

Uruchomienie w

ą

tku

public void start() {
if (watekZegara

==

null) {

watekZegara = new Thread(this, "Zegar");

watekZegara.start();

}
}

Powstaj

ą

zasoby systemowe dla w

ą

tku, wybierany jest w

ą

tek i wołana

jest dla niego metoda

run()

. W

ą

tek b

ę

dzie w stanie "

wykonywania

"

(

running

).

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 20

Zablokowanie (zawieszenie) w

ą

tku

Wykonywanie w

ą

tku zostaje

zawieszone

(stan „

zablokowany

”), gdy:



wywołana zostanie jego metoda

sleep()

;



w

ą

tek woła metod

ę

wait()

dla oczekiwania na spełnienie warunku;



w

ą

tek zablokuje si

ę

w oczekiwaniu na operacj

ę

we/wy.

Aby w

ą

tek powrócił do stanu „wykonywania” ze stanu „zablokowania”:



musi upłyn

ąć

okre

ś

lony w wywołaniu

sleep()

czas podany liczb

ą

milisekund;



inny obiekt musi powiadomi

ć

nasz u

ś

piony w

ą

tek o zmianie warunku

wywołuj

ą

c

notify

lub

notifyAll

;



operacja we/wy, blokuj

ą

ca w

ą

tek, musi si

ę

zako

ń

czy

ć

.

Ust

ą

pienie czasu procesora innym w

ą

tkom

W

ą

tek mo

ż

e samoczynnie ust

ą

pi

ć

czas procesora

bez przechodzenia

w stan

zawieszenia

wołaj

ą

c metod

ę

yield()

– przejdzie on na koniec

kolejki w

ą

tkom o jego priorytecie i da szans

ę

na wykonanie si

ę

innym

w

ą

tkom o tym samym priorytecie co ust

ę

puj

ą

cy w

ą

tek.

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 21

Zako

ń

czenie w

ą

tku

W

ą

tek ko

ń

czy si

ę

samodzielnie gdy zako

ń

czy si

ę

metoda

run().

W przykładzie z apletem

Zegar

o zako

ń

czeniu p

ę

tli metody

run()

decyduje warunek:

while (watekZegara

==

mojWatek) {

Gdy przegl

ą

darka opuszcza stron

ę

, na której wykonuje si

ę

aplet wtedy

woła ona metod

ę

stop()

dla apletu. W aplecie

Zegar

oznacza to,

ż

e:

public void stop() {
watekZegara = null;

// Zmieniamy warunek wykonywania się run()

}

Teraz metoda

run()

zako

ń

czy si

ę

-> w

ą

tek jest w stanie „

zako

ń

czony

”.

Metoda klasy

Thread: isAlive()

boolean

isAlive()

Wynik zwracany przez

isAlive

:



true

- gdy w

ą

tek jest w stanie „wykonywania” lub „zablokowania”;



false

- gdy w

ą

tek jest w stanie

nowo utworzony

” lub

zako

ń

czony”.

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 22

4) Priorytet w

ą

tku - szeregowanie

Priorytet w

ą

tku decyduje o przydzieleniu czasu procesora jednemu z

w

ą

tków b

ę

d

ą

cych w stanie „wykonywania” – wybraniu go spo

ś

ród

konkuruj

ą

cych w

ą

tków.


Java

realizuje

deterministyczny

algorytm

szeregowania

(„scheduling”) w oparciu o priorytety:



W

ą

tek dziedziczy swój priorytet od w

ą

tku który go utworzył.



Metoda

setPriority

umo

ż

liwia zmian

ę

priorytetu - mo

ż

liwe s

ą

warto

ś

ci

od

MIN_PRIORITY

do

MAX_PRIORITY

(stałe zdefiniowane w

Thread

).



Wybierany jest w

ą

tek o najwy

ż

szym priorytecie - z dwóch równych

nast

ę

pny z kolejki FIFO dla danego priorytetu.

W

ą

tek wykonuje si

ę

w procesorze dopóki nie zajdzie jeden z

przypadków:



Pojawi si

ę

w

ą

tek o wy

ż

szym priorytecie - w stanie „

wykonywania

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 23



W

ą

tek ust

ę

puje sam (metoda

yield

)

lub ko

ń

czy si

ę

jego metoda

run

.



W systemach pracuj

ą

cych z podziałem czasu w

ą

tków – gdy jego

kwant czasu ko

ń

czy si

ę

(zale

ż

y to od implementacji klasy

Thread

).

Wtedy kolejny w

ą

tek b

ę

dzie wybrany do wykonania.


Algorytm wyboru jest

wywłaszczaj

ą

cy

- z chwil

ą

pojawienia si

ę

w

ą

tku

o wy

ż

szym priorytecie wykonywany w

ą

tek zostaje wywłaszczony.


Java

nie realizuje podziału czasu

, w

ą

tek nie zostanie wywłaszczony

przez inny w

ą

tek o tym samym priorytecie. Jednak implementacja

klasy

Thread

w danym systemie mo

ż

e realizowa

ć

prac

ą

z podziałem

czasu CPU.

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 24

6.4 Synchronizacja pracy w

ą

tków

Do tej pory rozpatrywali

ś

my w

ą

tki, które mog

ą

wykonywa

ć

si

ę

asynchronicznie

wzgl

ę

dem

siebie.

Jednak

w

ą

tki

mog

ą

wykorzystywa

ć

wyniki pracy

innych w

ą

tków. W szczególno

ś

ci w

ą

tki

mog

ą

dzieli

ć

te same dane – jednocze

ś

nie odwoływa

ć

si

ę

do nich

.

Wtedy ich praca musi by

ć

synchronizowana.

Przykład.
Producent

generuje dane, zapisuje je do obiektu sklad klasy Skladzik a

te s

ą

nast

ę

pnie odczytywane i "konsumowane" przez

konsumenta

.

Niech producent generuje liczb

ę

pomi

ę

dzy 0 a 9 (wł

ą

cznie),

zapami

ę

tuje j

ą

w obiekcie klasy

Skladzik

i wy

ś

wietla t

ę

liczb

ę

.

Nast

ę

pnie "zasypia" na losowo dobierany czas (pomi

ę

dzy 0 a 100 ms)

i znowu powtarza cykl generacji danych.

public class Producent extends Thread {
private Skladzik sklad;
private int number;

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 25

public Producent (Skladzik c, int number) {
sklad = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
skład.put(i);
System.out.println("Producent #" + this.number + " położył: " + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}

Konsument pobiera wszystkie liczby jak szybko to jest mo

ż

liwe.

public class Konsument extends Thread {
private Skladzik sklad;

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 26

private int number;
public Konsument(Skladzik c, int number) {
sklad = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = sklad.get();
System.out.println("Konsument #" + this.number+"pobrał: "+ value);
}
}
}

// Klasa główna programu

public class ProducentKonsumentTest {
public static void main(String[] args) {
Skladzik c = new Skladzik();
Producent p1 = new Producent(c, 1);

// Utwórz producenta

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 27

Konsument c1 = new Konsument(c, 1);

// Utwórz konsumenta

p1.start();

// Uruchom wątek producenta

c1.start();

// Uruchom wątek konsumenta

}
}

Producent i konsument wymieniaj

ą

dane poprzez

wspólny obiekt

Skladzik

. Ale obie klasy "

Konsument

" i "

Producent

"

nie synchronizuj

ą

jawnie swoich działa

ń

, nie zapewniaj

ą

tego,

ż

eby konsument

otrzymywał ka

ż

d

ą

dan

ą

tylko raz

.

Dlatego w tym przykładzie synchronizacja

musi by

ć

zrealizowana na

"niskim poziomie"

przez metody "

get

" i "

put

" klasy

Składzik

. W innym

przypadku łatwo mo

ż

e powsta

ć

"

hazard

" w dost

ę

pie do obiektu przez

oba w

ą

tki.

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 28

Sposoby synchronizacji:



zablokowanie innemu w

ą

tkowi dost

ę

pu do obiektu

(sekcja

krytyczna)

– kwalifikator metody

synchronized

.



powiadamianie si

ę

w

ą

tków - metody klasy

Thread

-

wait, notify

,

notifyAll

.

Sekcja krytyczna

Przykład (c.d.)

W podanym przykładzie metody

put

i

get

klasy

Skladzik

tworz

ą

sekcje krytyczne.

public class Skladzik {
private int contents;
private boolean available = false;
public synchronized int get() {
...
}
public synchronized void put(int value) {
...
}

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 29

}

Z ka

ż

dym obiektem klasy

Skladzik

zwi

ą

zany b

ę

dzie

semafor

. Je

ś

li

wołana jest metoda synchronizowana to obiekt zostaje zablokowany.

Inny w

ą

tek nie mo

ż

e wykona

ć

metody synchronizowanej

na tym

samym obiekcie do momentu odblokowania obiektu. Uniemo

ż

liwia to

powstanie hazardu w dost

ę

pie do obiektu.

Metody

notifyAll

i

wait

W

ą

tki musz

ą

si

ę

móc powiadamia

ć

,

ż

e czekaj

ą

na nie dane (

wait

) i

ż

e

dane zostały dostarczone (

notify, notifyAll

).

Przykład (c.d.)

Nowe definicje metod

get

i

put

klasy

Skladzik

public synchronized int get() {
while (available == false) {
try {
wait();

// Oczekuj na położenie danej przez producenta

} catch (InterruptedException e) {
}

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 30

}
available = false;
notifyAll();

// Powiadom producenta o pobraniu danej

return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();

// Oczekuj na pobranie danej przez konsumenta

} catch (InterruptedException e) {
}
}
contents = value;
available = true;

notifyAll();

// Powiadom konsumenta o położeniu danej

}

Metod

wait

zwalnia semafor "trzymany" przez "Konsumenta" na

obiekcie "sklad" i oczekuje na powiadomienie od "Producenta".

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 31



Metoda

notifyAll

budzi do

ż

ycia wszystkie w

ą

tki, które oczekuj

ą

na

dany obiekt (w tym przypadku "sklad"). Konkuruj

ą

one wtedy o

dost

ę

p do obiektu.



Metoda

notify

w klasie

Object

: "budzi" dowolny w

ą

tek spo

ś

ród

oczekuj

ą

cych.



W klasie

Object

zdefiniowano trzy wersje metody

wait

:



wait()

- oczekuje w niesko

ń

czono

ść

na nadej

ś

cie powiadomienia;



wait (long timeout)

- oczekuje najwy

ż

ej liczb

ę

timeout

milisekund;



wait (long timeout, int nanos)

- oczekuje najwy

ż

ej liczb

ę

timeout

milisekund plus

nanos

nanosekund.

Nale

ż

y unika

ć

"wygłodzenia” i zakleszcze

ń

w

ą

tków.

"Wygłodzenie" w

ą

tku wyst

ą

pi gdy jeden lub wi

ę

cej w

ą

tków nie

otrzymuje dost

ę

pu do zasobów.

Zakleszczenie to ko

ń

cowe stadium „wygłodzenia” - w

ą

tki czekaj

ą

na

spełnienie niemo

ż

liwego warunku.

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 32

6.5 Grupowanie w

ą

tków

Klasa

java.lang.ThreadGroup -

umo

ż

liwia zebranie w

ą

tków w jeden

obiekt i jednoczesn

ą

manipulacj

ę

nimi wszystkimi.

Podczas tworzenia w

ą

tku zostaje on przydzielony do jakie

ś

grupy i

musi ju

ż

tam pozosta

ć

.

Domy

ś

lna grupa w

ą

tków dla aplikacji to jest

main

.

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 33

Utworzenie nowej grupy w

ą

tków o nazwie

name

:

ThreadGroup(String name)

ThreadGroup(ThreadGroup parent, String name)

Np. utworzenie grupy jako elementu domy

ś

lnej grupy w

ą

tków

main

:

ThreadGroup myThreadGroup = new ThreadGroup(“Moja grupa");

Je

ś

li podczas tworzenia nowego w

ą

tku nie specyfikujemy jego grupy to

zostanie on zaliczony do grupy tego w

ą

tku, który go utworzył.


Trzy konstruktory klasy

Thread

umo

ż

liwiaj

ą

utworzenie i dodanie w

ą

tku

do jawnie podanej grupy:

public Thread(ThreadGroup group, Runnable runnable)
public Thread(ThreadGroup group, String name)
public Thread(ThreadGroup group, Runnable runnable, String name)

Np.

Utworzenie w

ą

tku w nowej grupie:

Thread myThread = new Thread(myThreadGroup, "watek w grupie");


Okre

ś

lenie grupy dla w

ą

tku - metoda

getThreadGroup

, np.:

theGroup = myThread.getThreadGroup();

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 34

Metody klasy

ThreadGroup

Zarz

ą

dzanie kolekcj

ą



activeCount()

- podaje liczb

ę

aktywnych w

ą

tków w grupie;



activeGroupCount()

– podaje liczb

ę

aktywnych grup w

ą

tków w grupie

.

Klasa implementuje interfejs

Enumerate

, co pozwala m.in. na pobranie

listy aktywnych w

ą

tków tej grupy.

Np.

public class EnumerateTest {
public void listCurrentThreads() {
ThreadGroup currentGroup =
Thread.currentThread().getThreadGroup();
int numThreads = currentGroup.activeCount();
Thread[] listOfThreads = new Thread[numThreads];
currentGroup.enumerate(listOfThreads);
for (int i = 0; i < numThreads; i++)
System.out.println("Wątek #" + i + " = " + listOfThreads[i].getName());
}
}

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 35

Przetwarzanie grupy w

ą

tków



getMaxPriority, setMaxPriority

// Ustawianie priorytetu



getDaemon, setDaemon



getName



getParent, parentOf



toString

Np.

public class MaxPriorityTest {
public static void main(String[] args) {
ThreadGroup groupNORM = new ThreadGroup(

// Utworzenie grupy

"Normalny priorytet grupy");
Thread priorityMAX = new Thread(groupNORM,

// Dodanie wątku

"Wątek o maksymalnym priorytecie");

// Ustaw priorytet wątku na maksymalnie możliwy (10)

priorityMAX.setPriority(Thread.MAX_PRIORITY);

// Ustaw maksymalny priorytet grupy na normalny (5)

groupNORM.setMaxPriority(Thread.NORM_PRIORITY);

System.out.println("Maksymalny priorytet grupy = " +

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 36

groupNORM.getMaxPriority());

System.out.println("Priorytet wątku = " + priorityMAX.getPriority());
}
}

Wynik wykonania:

Maksymalny priorytet grupy = 5
Priorytet wątku = 10

Metody operuj

ą

ce na stanie wszystkich w

ą

tkach grupy jednocze

ś

nie



resume() -

wznów



stop() -

zatrzymaj



suspend() -

zawie

ś

Metody te zmieniaj

ą

stan wszystkich w

ą

tków grupy jednocze

ś

nie.

Uwaga: poniewa

ż

wykorzystuj

ą

one metody

resume, stop

i

suspend

klasy

Thread

nie s

ą

one zabezpieczone przed w

ą

tkami (tzn.

jednoczesnym u

ż

yciem przez wi

ę

cej ni

ż

jeden w

ą

tek).

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 37

Metody kontroli dost

ę

pu

Obie klasy współpracuj

ą

z klas

ą

SecurityManager

.

Klasy

Thread

i

ThreadGroup

posiadaj

ą

metod

ę

checkAccess

, która

wywołuje metod

ę

checkAccess

aktualnego „security managera”,

sprawdzaj

ą

c

ą

prawo dost

ę

pu dla grupy - zgłasza wyj

ą

tek

SecurityException

je

ś

li nie jest to mo

ż

liwe.

Poni

ż

sze metody klasy

ThreadGroup

wywołuj

ą

metod

ę

checkAccess

zanim wykonaj

ą

swoj

ą

akcj

ę

(regulowany dost

ę

p):

ThreadGroup(ThreadGroup parent, String name)

setDaemon(boolean isDaemon)

setMaxPriority(int maxPriority)

stop

suspend

resume

destroy

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 38

Lista metod klasy

Thread

, które wywołuj

ą

checkAccess

zanim wykonaj

ą

swoj

ą

akcj

ę

:

konstruktory specyfikujące grupę wątków;

stop

suspend

resume

setPriority(int priority)

setName(String name)

setDaemon(boolean isDaemon)

background image

6. W

ą

tki.

W. Kasprzak: Programowanie zdarzeniowe

6 - 39

Podsumowanie

Pakiety wspomagaj

ą

ce programowanie wielow

ą

tkowe



java.lang.Thread -

Bazowa klasa dla w

ą

tków w Javie.



java.lang.Runnable

-

Interfejs

Runnable

zawiera metod

ę

run

,

wymagan

ą

dla ka

ż

dego w

ą

tku.



java.lang.Object -

Klasa główna

Object

zawiera definicje 3 metod

przeznaczonych do synchronizacji w

ą

tków

:

wait, notify, notifyAll

.



java.lang.ThreadGroup -

Ka

ż

dy w

ą

tek nale

ż

y do jakie

ś

grupy,

zwykle skupiaj

ą

cej powi

ą

zane ze sob

ą

w

ą

tki.



java.lang.ThreadDeath

-

Wymuszenie zako

ń

czenia pracy w

ą

tku jest

mo

ż

liwe dzi

ę

ki

przekazaniu

mu obiektu klasy

ThreadDeath

.

Elementy j

ę

zyka wspomagaj

ą

ce w

ą

tki

Słowo kluczowe w Javie przeznaczone do synchronizacji w

ą

tków:

synchronized

.

Elementy

ś

rodowiska wykonania wspomagaj

ą

ce w

ą

tki

W

ś

rodowisku wykonania Javy wyst

ę

puje szeregowanie w

ą

tków.


Wyszukiwarka

Podobne podstrony:
Proz-S6
Proz S2 id 402992 Nieznany
mechanika gruntow s6
Proz S12 id 402989 Nieznany
S6 Psychologia róznic indywidualnych wykład 7 20130504, Notatki RI
sciaga z wykladow, WTD, semestr V, M Bociong, S6 R3 - Towaroznawstwo Drzewne
chemia proz maj 2011 cke id 112 Nieznany
REw Hydr BW s6 Zrealizowany zakres wykladu, Ćwiczenia
S6 Psychologia róznic indywidualnych wykład 2 20130315, Notatki(1)
Audi A6 S6 RS6, 1997 2004
Zadania oleju s6
AudiA6 S6 RS6, 2008 2011
08 09 Lab PA s6 dz
kolokwium nr 1 organizacja, WTD, semestr V, M Bociong, S6 R3 - Organizacja i zarządzanie, kolokwium
Procesowe dobre aktualne s6
s6, Studia, Materiałoznastwo, Metaloznastwo i Podstawy Obrobki Cieplnej, Meteloznastwo
popyk zestawy, WTD, semestr V, M Bociong, S6 R3 - Organizacja i zarządzanie, Organizacja

więcej podobnych podstron