J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
1 / 37
Programowanie współbie
ż
na
J
ę
zyk Java – w
ą
tki
(streszczenie)
Paweł Rogali
ń
ski
Instytut Informatyki, Automatyki i Robotyki
Politechniki Wrocławskiej
pawel.rogalinski
@
pwr.wroc.pl
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
2 / 37
Podstawowe poj
ę
cia: procesy i w
ą
tki
Proces
to wykonuj
ą
cy si
ę
program wraz z dynamicznie przydzielanymi mu przez
system zasobami (np. pami
ę
ci
ą
operacyjn
ą
, zasobami plikowymi). Ka
ż
dy proces ma
własn
ą
przestrze
ń
adresow
ą
.
Systemy wielozadaniowe pozwalaj
ą
na równoległe (teoretycznie) wykonywanie
wielu procesów, z których ka
ż
dy ma swój kontekst i swoje zasoby.
W
ą
tek
to sekwencja działa
ń
, która wykonuje si
ę
w kontek
ś
cie danego procesu
(programu)
Ka
ż
dy proces ma co najmniej jeden wykonuj
ą
cy si
ę
w
ą
tek. W systemach
wielow
ą
tkowych proces mo
ż
e wykonywa
ć
równolegle (teoretycznie) wiele w
ą
tków, które
wykonuj
ą
si
ę
jednej przestrzeni adresowej procesu.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
3 / 37
Podstawowe poj
ę
cia: procesy i w
ą
tki
Równoległo
ść
działania w
ą
tków osi
ą
gana jest przez mechanizm przydzielania czasu
procesora poszczególnym wykonuj
ą
cym si
ę
w
ą
tkom. Ka
ż
dy w
ą
tek uzyskuje dost
ę
p do
procesora na krótki czas (kwant czasu), po czym „oddaje procesor” innemu w
ą
tkowi.
Zmiana w
ą
tku wykonywanego przez procesor mo
ż
e dokonywa
ć
si
ę
na zasadzie:
współpracy
(cooperative multitasking), w
ą
tek sam decyduje, kiedy odda
ć
czas
procesowa innym w
ą
tkom,
wywłaszczania
(pre-emptive multitasking), o dost
ę
pie w
ą
tków do procesora
decyduje systemowy zarz
ą
dca w
ą
tków, który przydziela w
ą
tkowi kwant czasu
procesora, po upływie którego odsuwa w
ą
tek od procesora i przydziela kolejny
kwant czasu innemu w
ą
tkowi.
Java jest j
ę
zykiem wieloplatformowym, a ró
ż
ne systemy operacyjne stosuj
ą
ró
ż
ne
mechanizmy udost
ę
pniania w
ą
tkom procesora. Programy wielow
ą
tkowe powinny by
ć
tak pisane, by działały zarówno w
ś
rodowisku „współpracy” jak i „wywłaszczania”
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
4 / 37
Tworzenie i uruchamianie w
ą
tków
Uruchamianiem w
ą
tków i zarz
ą
dzaniem nimi zajmuje si
ę
klasa
Thread
.
Aby uruchomi
ć
w
ą
tek, nale
ż
y utworzy
ć
obiekt klasy
Thread
i dla tego obiektu wywoła
ć
metod
ę
start()
.
Kod wykonuj
ą
cy si
ę
jako w
ą
tek – sekwencja działa
ń
wykonuj
ą
ca si
ę
równolegle z
innymi działaniami programu – okre
ś
lany jest przez obiekt implementuj
ą
cy interfejs
Runnable
, który zawiera deklaracj
ę
metody
run()
.
Metoda
run()
okre
ś
la to co ma robi
ć
w
ą
tek.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
5 / 37
Główne metody klasy
Thread
1. Uruchamianie i zatrzymywanie w
ą
tków:
start
- uruchomienie w
ą
tku,
stop
– zako
ń
czenie w
ą
tku (metoda niezalecana),
run
- kod wykonywany w ramach w
ą
tku.
2. Identyfikacja w
ą
tków:
currentThread
- metoda zwraca identyfikator w
ą
tku bie
żą
cego,
setName
- ustawienie nazwy w
ą
tku,
getName
-odczytanie nazwy w
ą
tku,
isAlive
- sprawdzenie czy w
ą
tek działa,
toString
- uzyskanie atrybutów w
ą
tku.
3. Priorytety i szeregowanie w
ą
tków:
getPriority
- odczytanie priorytetu w
ą
tku,
setPriority
- stawienie priorytetu w
ą
tku,
yield
- wywołanie szeregowania.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
6 / 37
Główne metody klasy
Thread
c.d.
4. Synchronizacja w
ą
tków:
sleep
zawieszenie wykonania w
ą
tku na dany okres czasu,
join
- czekanie na zako
ń
czenie innego w
ą
tku,
wait
- czekanie w monitorze,
notify
- odblokowanie w
ą
tku zablokowanego na monitorze,
notifyAll
- odblokowanie wszystkich w
ą
tków zablokowanych na
monitorze,
interrupt
- odblokowanie zawieszonego w
ą
tku,
suspend
- zablokowanie w
ą
tku,
resume
- odblokowanie w
ą
tku zawieszonego przez
suspend
,
setDaemon
- ustanowienie w
ą
tku demonem,
isDaemon
- testowanie czy w
ą
tek jest demonem.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
7 / 37
Tworzenie w
ą
tków
Mo
ż
liwe s
ą
dwa sposoby tworzenia nowego w
ą
tku:
poprzez dziedziczenie klasy
Thread
poprzez implementacj
ę
interfejsu
Runnable
.
Sposób drugi stosujemy wówczas, gdy klasa reprezentuj
ą
ca w
ą
tek musi dziedziczy
ć
po innej ni
ż
Thread
klasie (Java nie dopuszcza dziedziczenia wielobazowego).
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
8 / 37
Tworzenie w
ą
tku – dziedziczenie klasy
Thread
Aby utworzy
ć
w
ą
tek jako klasa potomna od klasy
Thread
nale
ż
y:
1. Utworzy
ć
now
ą
klas
ę
(na przykład o nazwie
Tklasa
) jako potomn
ą
klasy
Thread
i nadpisa
ć
metod
ę
run()
klasy macierzystej. Metoda ta ma zawiera
ć
kod do
wykonania w ramach tworzonego w
ą
tku.
class TKlasa extends Thread {
....
void run() {
// Kod w
ą
tku
}
....
}
2. Utworzy
ć
obiekt nowej klasy
Tklasa
(na przykład
thr
):
TKlasa thr = new TKlasa(...);
3. Wykona
ć
metod
ę
start()
klasy
TKlasa
dziedziczon
ą
z klasy macierzystej:
thr.start();
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
9 / 37
Tworzenie w
ą
tku – dziedziczenie klasy
Thread
class
NowyWatek
extends
Thread
{
public
void
run()
{ System.out.println(
" Nowy watek : POCZATEK"
);
try
{
for
(
int
i = 5; i > 0; i--)
{ System.out.println(
" Nowy watek: "
+ i);
Thread.sleep(500);
}
}
catch
(InterruptedException e) {}
System.out.println(
" Nowy watek : KONIEC"
);
}
}
class
GlownyWatek
{
public
static
void
main(String args[])
{ System.out.println(
" Glowny watek: POCZATEK"
);
System.out.println(
" Glowny watek: Tworze Nowy Watek"
);
NowyWatek nowyWatek =
new
NowyWatek();
System.out.println(
" Glowny watek: Uruchamiam Nowy watek"
);
nowyWatek.start();
try
{
for
(
int
i = 5; i > 0; i--)
{ System.out.println(
" Glowny watek: "
+ i);
Thread.sleep(1000);
}
}
catch
(InterruptedException e) {}
System.out.println(
" Glowny watek: KONIEC"
);
}
}
tworzenie
nowego watka
uruchomienie
nowego watka
działanie
nowego watka
działanie
głównego
watka
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
10 / 37
Tworzenie w
ą
tku – dziedziczenie klasy
Thread
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
11 / 37
Tworzenie w
ą
tku – implement. interfejsu
Runnable
Aby utworzy
ć
w
ą
tek korzystaj
ą
c z interfejsu
Runnable
nale
ż
y:
1. Utworzy
ć
now
ą
klas
ę
(np. o nazwie
RKlasa
) dziedzicz
ą
c
ą
po interesuj
ą
cej na
innej klasie (np. o nazwie
InnaKlasa
) i implementuj
ą
c
ą
interfejs
Runnable
. W
ramach tej nowej klasy utworzy
ć
metod
ę
run()
, która wykonywała b
ę
dzie
żą
dane
czynno
ś
ci.
class RKlasa extends InnaKlasa implements Runnable {
public void run() {
// Zawarto
ść
metody run
}
}
2. Utworzy
ć
obiekt tej nowej klasy
Rklasa r1 = new RKlasa();
3. Utworzy
ć
obiekt klasy
Thread
przekazuj
ą
c obiekt wcze
ś
niej utworzonej klasy
jako parametr konstruktora klasy
Thread
.
Thread t1 = new Thread(r1);
4. Uruchomi
ć
watek wykonuj
ą
c metod
ę
start()
klasy
Thread
.
t1.start();
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
12 / 37
Tworzenie w
ą
tku – implement. interfejsu
Runable
class
NowyWatek
implements
Runnable
{
public
void
run()
{ System.out.println(
" Nowy watek : POCZATEK"
);
try
{
for
(
int
i = 5; i > 0; i--)
{ System.out.println(
" Nowy watek: "
+ i);
Thread.sleep(500);
}
}
catch
(InterruptedException e) {}
System.out.println(
" Nowy watek : KONIEC"
);
} }
class
GlownyWatek
{
public
static
void
main(String args[])
{ System.out.println(
" Glowny watek: POCZATEK"
);
System.out.println(
" Glowny watek: Tworze Nowy watek"
);
NowyWatek nowyWatek =
new
NowyWatek();
Thread thread =
new
Thread(nowyWatek);
System.out.println(
" Glowny watek: Uruchamiam Nowy watek"
);
thread.start();
try
{ for(int i = 5; i > 0; i--)
{ System.out.println(
" Glowny watek: "
+ i);
Thread.sleep(1000);
}
}
catch
(InterruptedException e) {}
System.out.println(
" Glowny watek: KONIEC"
);
} }
działanie
nowego watka
tworzenie
nowego watka
uruchomienie
nowego watka
działanie
głównego
watka
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
13 / 37
Ko
ń
czenie pracy w
ą
tku
W
ą
tek ko
ń
czy prac
ę
w sposób naturalny gdy zako
ń
czy si
ę
jego metoda
run()
.
Wykonanie metody
stop()
powoduje zatrzymanie innego w
ą
tku. Gdy
zatrzymywany w
ą
tek znajduje si
ę
wewn
ą
trz monitora to wej
ś
cie do tego monitora
zostaje odblokowane. Metoda ta jest wycofana (istnieje ale u
ż
ycie jej nie jest zalecane).
Powodem jest fakt
ż
e wywołuj
ą
c te metod
ę
nie wiemy w jakim stanie jest zatrzymywany
w
ą
tek. Gdy wykonuje jakie
ś
krytyczne operacje mo
ż
e pozostawi
ć
obiekt w
nieprawidłowym stanie.
Je
ś
li chcemy programowo zako
ń
czy
ć
prac
ę
w
ą
tku, powinni
ś
my zapewni
ć
w
metodzie
run()
sprawdzanie warunku zako
ń
czenia (ustalanego programowo) i je
ś
li
warunek ten jest spełniony, spowodowa
ć
wyj
ś
cie z metody
run()
. Warunek
zako
ń
czenia mo
ż
e by
ć
formułowany w postaci jakiej
ś
zmiennej, która jest ustalana przez
inne fragmenty kodu programu (wykonywane w innym w
ą
tku).
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
14 / 37
Ko
ń
czenie pracy w
ą
tku - przykład
class
NowyWatek
extends
Thread
{
boolean
zakoncz =
false
;
public
void
run()
{ System.out.println(
" Nowy watek : POCZATEK"
);
while
(zakoncz==
false
)
{
try
{ sleep(200);
}
catch
(InterruptedException e) {}
System.out.print(
" ."
);
}
System.out.println(
"\n Nowy watek : KONIEC"
);
}
}
class
GlownyWatek
{
public
static
void
main(String args[])
{ System.out.println(
" Glowny watek: POCZATEK"
);
System.out.println(
" Glowny watek: Tworze Nowy watek"
);
NowyWatek nowyWatek =
new
NowyWatek();
nowyWatek.start();
try
{ Thread.sleep(10000);
}
catch
(InterruptedException e) {}
nowyWatek.zakoncz =
true
;
try
{ Thread.sleep(2000);
}
catch
(InterruptedException e) {}
System.out.println(
" Glowny watek: KONIEC"
);
}
}
testowanie warunku
zako
ń
czenia watka
wymuszenie warunku
zako
ń
czenia watka
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
15 / 37
Ko
ń
czenie pracy w
ą
tku - przykład
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
16 / 37
Stany w
ą
tków
W
ą
tek mo
ż
e znajdowa
ć
si
ę
w jednym z czterech stanów:
utworzony
(ang. new thread) - obiekt w
ą
tku został ju
ż
utworzony ale nie
wykonano metody
start()
, a wi
ę
c w
ą
tek nie jest jeszcze szeregowany,
wykonywalny
(ang. runnable) - W
ą
tek posiada wszystkie zasoby aby by
ć
wykonywany. B
ę
dzie wykonywany gdy tylko procedura szereguj
ą
ca przydzieli
mu procesor,
zablokowany
(ang. blocked) -W
ą
tek nie mo
ż
e by
ć
wykonywany gdy
ż
brakuje
mu pewnych zasobów. Dotyczy to w szczególno
ś
ci operacji synchronizacyjnych
(w
ą
tek zablokowany na wej
ś
ciu do monitora, operacje
wait
,
sleep
,
join
) i
operacji wej
ś
cia wyj
ś
cia,
zako
ń
czony
(ang. dead) - Stan po wykonaniu metody
stop()
. Zalecanym
sposobem ko
ń
czenia w
ą
tku jest zako
ń
czeni metody
run()
.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
17 / 37
Stany w
ą
tków
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
18 / 37
Stany w
ą
tków
Przej
ś
cie od stanu
wykonywalny
do
zablokowany
nast
ę
puje gdy:
1. w
ą
tek chce wej
ść
do zablokowanego monitora
2. wykonana została metoda
wait()
,
join()
,
suspend()
3. wywołano metod
ę
sleep(...)
4. w
ą
tek wykonał operacj
ę
wej
ś
cia / wyj
ś
cia.
Powrót od stanu
zablokowany
do
wykonywany
nast
ę
puje gdy:
1. monitor został odblokowany
2. inny w
ą
tek wykonał operacja odblokowania zablokowanego w
ą
tku – wywołał
metod
ę
notify()
,
notifyAll()
,
resume()
,
interrupt()
3. gdy w
ą
tek zako
ń
czył wykonywanie metody
sleep()
– upłyn
ą
ł zadany interwał
czasu.
4. je
ż
eli w
ą
tek czekał na zako
ń
czenie operacji wej
ś
cia / wyj
ś
cia – operacja ta si
ę
zako
ń
czyła
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
19 / 37
Synchronizacja w
ą
tków - przykład
Pytanie:
Jak
ą
warto
ść
zwróci metoda
balance()
?
class Balance
{
private int number = 0;
public int balance()
{ number++;
number--;
return number;
}
}
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
20 / 37
Synchronizacja w
ą
tków – przykład c.d.
Zmiany warto
ś
ci zmiennej
number
gdy wykonywany jest tylko jeden w
ą
tek:
Warto
ś
ci zmiennej
number
wykonywane instrukcje
w w
ą
tku
0
. . .
0
balance(){
0
number++;
1
number--;
0
return number;
}
0
. . .
zwróci
warto
ść
0
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
21 / 37
Synchronizacja w
ą
tków – przykład c.d.
Zmiany warto
ś
ci zmiennej
number
gdy wykonywane s
ą
dwa w
ą
tki:
Warto
ś
ci zmiennej
number
wykonywane instrukcje
w pierwszym w
ą
tku
wykonywane instrukcje
w drugim w
ą
tku
0
. . .
0
balance(){
0
number++;
1
number--;
0
return number;
}
0
. . .
0
. . .
0
balance(){
0
number++;
1
number--;
0
return number;
}
0
. . .
zwróci
warto
ść
0
zwróci
warto
ść
0
wywłaszczenie
pierwszego
w
ą
tka
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
22 / 37
Synchronizacja w
ą
tków – przykład c.d.
Zmiany warto
ś
ci zmiennej
number
gdy wykonywane s
ą
dwa w
ą
tki:
Warto
ś
ci zmiennej
number
wykonywane instrukcje
w pierwszym w
ą
tku
wykonywane instrukcje
w drugim w
ą
tku
0
. . .
0
balance(){
0
number++;
1
. . .
1
balance(){
1
number++;
2
number--;
1
return number;
}
1
. . .
1
number--;
0
return number;
}
0
. . .
zwróci
warto
ść
0
wywłaszczenie
pierwszego
w
ą
tka
zwróci
warto
ść
1
wywłaszczenie
drugiego w
ą
tka
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
23 / 37
Synchronizacja w
ą
tków
– przykład c.d.
Zawsze musimy si
ę
liczy
ć
z tym,
ż
e w
ą
tki operuj
ą
ce na współdzielonych zmiennych
mog
ą
by
ć
wywłaszczone w trakcie operacji (nawet pojedynczej) i wobec tego stan
współdzielonej zmiennej mo
ż
e okaza
ć
si
ę
niespójny.
Testowanie programów wielow
ą
tkowych jest trudne, bowiem mo
ż
emy wiele
razy otrzyma
ć
wyniki, które wydaj
ą
si
ę
ś
wiadczy
ć
o poprawno
ś
ci programu,
a przy kolejnym uruchomieniu oka
ż
e si
ę
,
ż
e wynik jest nieprawidłowy.
Wyniki uruchamiania programów wielow
ą
tkowych mog
ą
by
ć
tak
ż
e ró
ż
ne
na ró
ż
nych platformach systemowych.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
24 / 37
Synchronizacja w
ą
tków
Komunikacja mi
ę
dzy w
ą
tkami opiera si
ę
na
wspólnej pami
ę
ci
. W takim przypadku
wyst
ę
puje zjawisko wy
ś
cigów.
Wy
ś
cigi
(ang. race conditions) – wynik działania procedur wykonywanych przez
w
ą
tki zale
ż
y od kolejno
ś
ci ich wykonania.
Gdy kilka w
ą
tków ma dost
ę
p do wspólnych danych i przynajmniej jeden je
modyfikuje wyst
ę
puje konieczno
ść
synchronizowania dost
ę
pu do wspólnych danych.
Synchronizacja
jest mechanizmem, który zapewnia,
ż
e kilka wykonuj
ą
cych si
ę
w
ą
tków:
nie b
ę
dzie równocze
ś
nie działa
ć
na tym samym obiekcie,
nie b
ę
dzie równocze
ś
nie wykonywa
ć
tego samego kodu.
Kod, który mo
ż
e by
ć
wykonywany w danym momencie tylko przez jeden w
ą
tek,
nazywa si
ę
sekcj
ą
krytyczn
ą
. W Javie sekcje krytyczne wprowadza si
ę
jako bloki lub
metody synchronizowane.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
25 / 37
Synchronizacja w
ą
tków - monitory
Ka
ż
dy egzemplarz klasy
Object
i jej podklas posiada
monitor
(ang. lock), który
ogranicza dost
ę
p do obiektu. Blokowanie obiektów jest sterowane słowem kluczowym
synchronized
.
Synchronizacja w Javie mo
ż
e by
ć
wykonana na poziomie:
metod – słowo kluczowe
synchronized
wyst
ę
puje przy definiowaniu metody:
public synchronized int balance()
{...}
instrukcji - słowo kluczowe
synchronized
wyst
ę
puje przy definiowaniu bloku
instrukcji:
synchronized( number )
{ number++;
number--;
}
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
26 / 37
Synchronizacja w
ą
tków
Kiedy w
ą
tek wywołuje na rzecz jakiego
ś
obiektu metod
ę
synchronizowan
ą
,
automatycznie zamykany jest monitor (obiekt jest zajmowany przez w
ą
tek). Inne w
ą
tki
usiłuj
ą
ce wywoła
ć
na rzecz tego obiektu metod
ę
synchronizowan
ą
(niekoniecznie t
ą
sam
ą
) lub usiłuj
ą
ce wykona
ć
instrukcj
ę
synchronized
z podan
ą
referencj
ą
do
zaj
ę
tego obiektu s
ą
blokowane i czekaj
ą
na zako
ń
czenie wykonywania metody lub
instrukcji
synchronized
przez w
ą
tek, który zaj
ą
ł obiekt (zamkn
ą
ł monitor).
Dowole zako
ń
czenie wykonywania metody synchronizowanej lub instrukcji
synchronized
zwalnia monitor, daj
ą
c czekaj
ą
cym w
ą
tkom mo
ż
liwo
ść
dost
ę
pu do
obiektu.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
27 / 37
Koordynacja w
ą
tków
Koordynacja w
ą
tków polega na zapewnieniu wła
ś
ciwej kolejno
ś
ci działa
ń
wykonywanych przez ró
ż
ne w
ą
tki na wspólnym zasobie. Do koordynacji w
ą
tków stosuje
si
ę
nast
ę
puj
ą
ce metody:
wait()
,
notify()
,
notifyAll().
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
28 / 37
Metoda
wait()
public final void wait();
public final void wait(long timeout);
public final void wait(long timeout,int nanos)
throws InterruptedException
Wykonanie metody powoduje zawieszenie bie
żą
cego w
ą
tku do czasu gdy inny
watek nie wykona metody
notify()
lub
notifyAll()
odnosz
ą
cej si
ę
do w
ą
tku, który
wykonał
wait()
. W
ą
tek wykonuj
ą
cy
wait(...)
musi by
ć
w posiadaniu monitora
dotycz
ą
cego synchronizowanego obiektu. Wykonanie
wait(...)
powoduje zwolnienie
monitora.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
29 / 37
Metoda
notify()
public final void notify();
Metoda powoduje odblokowanie jednego z w
ą
tków zablokowanych na monitorze
pewnego obiektu poprzez
wait()
. Który z czekaj
ą
cych w
ą
tków b
ę
dzie odblokowany nie
jest w definicji metody okre
ś
lone.
Odblokowany w
ą
tek nie b
ę
dzie natychmiast wykonywany – musi on jeszcze
zaczeka
ć
a
ż
zwolniona b
ę
dzie przez bie
żą
cy w
ą
tek blokada monitora. Odblokowany
w
ą
tek b
ę
dzie konkurował z innymi o nabycie blokady monitora. Metoda mo
ż
e by
ć
wykonana tylko przez w
ą
tek, który jest wła
ś
cicielem zajmuje monitor obiektu.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
30 / 37
Metoda
notifyAll()
public final void notifyAll()
Metoda powoduje odblokowanie wszystkich w
ą
tków zablokowanych na monitorze
pewnego obiektu poprzez uprzednie wykonanie
wait()
.
W
ą
tki b
ę
d
ą
jednak czekały a
ż
w
ą
tek bie
żą
cy nie zwolni blokady monitora.
Odblokowane w
ą
tki b
ę
d
ą
konkurowały o nabycie blokady monitora.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
31 / 37
Przykład koordynacji: Problem producent - konsument
.
Kilku producentów i konsumentów korzysta ze wspólnego zasobu jakim jest bufor.
Ka
ż
dy producent co pewien czas generuje liczby i umieszcza je w buforze.
Ka
ż
dy konsument co pewien czas pobiera liczb
ę
z bufora i wy
ś
wietla j
ą
na
ekranie.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
32 / 37
Przykład koordynacji: Problem producent - konsument
.
Ograniczenia:
1. Z bufora mo
ż
e korzysta
ć
w jedej chwili tylko jeden producent lub konsument,
2. Producent mo
ż
e umie
ś
ci
ć
liczb
ę
w buforze tylko wówczas, gdy bufor jest pusty.
W przeciwnym wypadku Producent musi czeka
ć
, a
ż
konsument zwolni miejsce
w buforze.
3. Konsument mo
ż
e pobra
ć
liczb
ę
z bufra tylko wtedy, gdy bufor nie jest pusty.
W przeciwnym wypadku konsument musi czeka
ć
ąż
jaki
ś
producent umie
ś
ci w
buforze liczb
ę
.
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
33 / 37
Klasa
Producent
public class Producent extends Thread
{
private Bufor buf;
private int number;
public Producent(Bufor c, int number)
{ buf = c;
this.number = number;
}
public void run()
{ for (int i = 0; i < 10; i++)
{
buf.put(i);
System.out.println("Producent #" +
this.number + " put: " + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
34 / 37
Klasa
Konsument
public class Konsument extends Thread
{
private Bufor buf;
private int number;
public Konsument(Bufor c, int number)
{ buf = c;
this.number = number;
}
public void run()
{ int value = 0;
for (int i = 0; i < 10; i++)
{
value = buf.get();
System.out.println("Konsument #" +
this.number + " got: " + value);
}
}
}
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
35 / 37
Klasa
ProducentKonsumentTest
public class ProducentConsumentTest
{
public static void main(String[] args)
{
Bufor c = new Bufor();
Producent p1 = new Producent(c, 1);
Konsument c1 = new Konsument(c, 1);
p1.start();
c1.start();
}
}
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
36 / 37
Klasa
Bufor
– metoda
get()
public class Bufor
{
private int contents;
private boolean available = false;
public synchronized int get()
{
while (available == false)
{
try {
wait();
} catch (InterruptedException e) { }
}
available = false;
notifyAll();
return contents;
}
J
ę
zyka Java – w
ą
tki
Autor: Paweł Rogali
ń
ski – Instytut Informatyki, Automatyki i Robotyki PWr
37 / 37
Klasa
Bufor
– metoda
put()
public synchronized void put(int value)
{
while (available == true)
{
try {
wait();
} catch (InterruptedException e) { }
}
contents = value;
available = true;
notifyAll();
}
}