[ Pobierz całość w formacie PDF ]
b dzie mog o jej u ywa równocze nie. Problem polega na tym, e suma cz ciowa jest prze-
chowywana w sk adowej sum, która jest modyfikowana przez ka dy w tek wywo uj cy metod
sumArray() dla obiektu sa zadeklarowanego jako static. Je li zatem dwa w tki wywo aj
równocze nie metod sa.sumArray(), wyniki jej dzia ania b d niepoprawne, poniewa sk a-
dowa sum b dzie przechowywa na przemian sumy cz ciowe obliczane przez ka dy z w t-
ków. Poni ej przedstawi em przyk ad dzia ania programu po usuni ciu s owa kluczowego
synchronized z deklaracji metody sumArray() (wynik dzia ania w Twoim przypadku mo e
si ró ni ).
W tek potomny nr 1 rozpoczyna dzia anie.
W tek potomny nr 2 rozpoczyna dzia anie.
W tek potomny nr 1 wyliczy sum cz ciow równ 1
W tek potomny nr 2 wyliczy sum cz ciow równ 1
W tek potomny nr 1 wyliczy sum cz ciow równ 3
W tek potomny nr 1 wyliczy sum cz ciow równ 8
W tek potomny nr 2 wyliczy sum cz ciow równ 8
W tek potomny nr 2 wyliczy sum cz ciow równ 11
W tek potomny nr 1 wyliczy sum cz ciow równ 15
W tek potomny nr 1 wyliczy sum cz ciow równ 20
W tek potomny nr 2 wyliczy sum cz ciow równ 24
W tek potomny nr 2 wyliczy sum cz ciow równ 29
W tek potomny nr 1 wyliczy sum równ 24
W tek potomny nr 1 ko czy dzia anie.
W tek potomny nr 2 wyliczy sum równ 29
W tek potomny nr 2 ko czy dzia anie.
Poleć książkę
Kup książkę
384 Java. Przewodnik dla pocz tkuj cych
Powy sze informacje pokazuj , e oba w tki potomne wywo uj równocze nie metod
sa.sumArray(), przypisuj c sk adowej sum niew a ciwe warto ci. Zanim przejdziemy do nast p-
nego zagadnienia, podsumujmy najwa niejsze fakty zwi zane z synchronizacj metod:
synchronizacja metody polega na umieszczeniu s owa kluczowego synchronized
w deklaracji metody;
synchronizacja dost pu do metody powoduje, e jej wywo anie dla dowolnego obiektu
powoduje jego zablokowanie i aden inny w tek nie mo e wywo a dla tego samego
obiektu adnej metody zadeklarowanej jako synchronized;
inne w tki próbuj ce wywo a metod zadeklarowan jako synchronized dla obiektu,
do którego dost p zosta zablokowany przez monitor, przechodz w stan oczekiwania
do momentu, w którym obiekt zostanie odblokowany;
gdy w tek ko czy wykonywanie metody synchronized, dost p do obiektu zostaje
odblokowany.
Synchronizacja instrukcji
Chocia deklarowanie metod jako synchronized stanowi prosty i efektywny sposób wyko-
rzystania mechanizmu synchronizacji, nie sprawdza si on we wszystkich sytuacjach. Na
przyk ad mo e wyst pi konieczno zapewnienia synchronizacji dost pu do metody, która
nie zosta a zadeklarowana jako synchronized. Mo e si to zdarzy , gdy u ywasz cudzych
klas i nie masz dost pu do ich kodu ród owego. Nie mo esz zatem doda s owa kluczowego
synchronized w deklaracji interesuj cej Ci metody. W jaki sposób mo esz zatem zapewni
synchronizacj dost pu do obiektu tej klasy? Rozwi zanie tego problemu jest na szcz cie
bardzo proste: wystarczy umieszcza wywo ania metod tej klasy w bloku oznaczonym jako
synchronized.
Poni ej przedstawi em ogóln posta bloku synchronized:
synchronized(refobj) {
// instrukcje wymagaj ce synchronizacji
}
W tym przypadku refobj jest referencj obiektu, do którego dost p wymaga synchronizacji.
Gdy w tek rozpocznie wykonywanie bloku synchronized, aden inny w tek nie mo e wywo a
metody dla obiektu refobj, dopóki bie cy w tek nie opu ci tego bloku.
Kolejny sposób synchronizacji wywo a metody sumArray() polega zatem na ich umieszczeniu
w bloku synchronized. Ilustruje to wersja programu przedstawiona na listingu 11.9.
Listing 11.9. Sync2.java
// U ywa bloku synchronized
// dla synchronizacji dost pu
// do metody sumArray.
class SumArray {
private int sum;
Poleć książkę
Kup książkę
Rozdzia 11. Programowanie wielow tkowe 385
int sumArray(int nums[]) { W tym wypadku dost p do metody sumArray()
sum = 0; // zeruje sum nie podlega synchronizacji.
for(int i=0; i
sum += nums[i];
System.out.println(Thread.currentThread().getName() +
" wyliczy sum cz ciow równ " + sum);
try {
Thread.sleep(10); // umo liwia prze czenie w tków
}
catch(InterruptedException exc) {
System.out.println("W tek zosta przerwany.");
}
}
return sum;
}
}
class MyThread implements Runnable {
Thread thrd;
static SumArray sa = new SumArray();
int a[];
int answer;
// Tworzy nowy w tek.
MyThread(String name, int nums[]) {
thrd = new Thread(this, name);
a = nums; [ Pobierz całość w formacie PDF ]
zanotowane.pl doc.pisz.pl pdf.pisz.pl freetocraft.keep.pl
b dzie mog o jej u ywa równocze nie. Problem polega na tym, e suma cz ciowa jest prze-
chowywana w sk adowej sum, która jest modyfikowana przez ka dy w tek wywo uj cy metod
sumArray() dla obiektu sa zadeklarowanego jako static. Je li zatem dwa w tki wywo aj
równocze nie metod sa.sumArray(), wyniki jej dzia ania b d niepoprawne, poniewa sk a-
dowa sum b dzie przechowywa na przemian sumy cz ciowe obliczane przez ka dy z w t-
ków. Poni ej przedstawi em przyk ad dzia ania programu po usuni ciu s owa kluczowego
synchronized z deklaracji metody sumArray() (wynik dzia ania w Twoim przypadku mo e
si ró ni ).
W tek potomny nr 1 rozpoczyna dzia anie.
W tek potomny nr 2 rozpoczyna dzia anie.
W tek potomny nr 1 wyliczy sum cz ciow równ 1
W tek potomny nr 2 wyliczy sum cz ciow równ 1
W tek potomny nr 1 wyliczy sum cz ciow równ 3
W tek potomny nr 1 wyliczy sum cz ciow równ 8
W tek potomny nr 2 wyliczy sum cz ciow równ 8
W tek potomny nr 2 wyliczy sum cz ciow równ 11
W tek potomny nr 1 wyliczy sum cz ciow równ 15
W tek potomny nr 1 wyliczy sum cz ciow równ 20
W tek potomny nr 2 wyliczy sum cz ciow równ 24
W tek potomny nr 2 wyliczy sum cz ciow równ 29
W tek potomny nr 1 wyliczy sum równ 24
W tek potomny nr 1 ko czy dzia anie.
W tek potomny nr 2 wyliczy sum równ 29
W tek potomny nr 2 ko czy dzia anie.
Poleć książkę
Kup książkę
384 Java. Przewodnik dla pocz tkuj cych
Powy sze informacje pokazuj , e oba w tki potomne wywo uj równocze nie metod
sa.sumArray(), przypisuj c sk adowej sum niew a ciwe warto ci. Zanim przejdziemy do nast p-
nego zagadnienia, podsumujmy najwa niejsze fakty zwi zane z synchronizacj metod:
synchronizacja metody polega na umieszczeniu s owa kluczowego synchronized
w deklaracji metody;
synchronizacja dost pu do metody powoduje, e jej wywo anie dla dowolnego obiektu
powoduje jego zablokowanie i aden inny w tek nie mo e wywo a dla tego samego
obiektu adnej metody zadeklarowanej jako synchronized;
inne w tki próbuj ce wywo a metod zadeklarowan jako synchronized dla obiektu,
do którego dost p zosta zablokowany przez monitor, przechodz w stan oczekiwania
do momentu, w którym obiekt zostanie odblokowany;
gdy w tek ko czy wykonywanie metody synchronized, dost p do obiektu zostaje
odblokowany.
Synchronizacja instrukcji
Chocia deklarowanie metod jako synchronized stanowi prosty i efektywny sposób wyko-
rzystania mechanizmu synchronizacji, nie sprawdza si on we wszystkich sytuacjach. Na
przyk ad mo e wyst pi konieczno zapewnienia synchronizacji dost pu do metody, która
nie zosta a zadeklarowana jako synchronized. Mo e si to zdarzy , gdy u ywasz cudzych
klas i nie masz dost pu do ich kodu ród owego. Nie mo esz zatem doda s owa kluczowego
synchronized w deklaracji interesuj cej Ci metody. W jaki sposób mo esz zatem zapewni
synchronizacj dost pu do obiektu tej klasy? Rozwi zanie tego problemu jest na szcz cie
bardzo proste: wystarczy umieszcza wywo ania metod tej klasy w bloku oznaczonym jako
synchronized.
Poni ej przedstawi em ogóln posta bloku synchronized:
synchronized(refobj) {
// instrukcje wymagaj ce synchronizacji
}
W tym przypadku refobj jest referencj obiektu, do którego dost p wymaga synchronizacji.
Gdy w tek rozpocznie wykonywanie bloku synchronized, aden inny w tek nie mo e wywo a
metody dla obiektu refobj, dopóki bie cy w tek nie opu ci tego bloku.
Kolejny sposób synchronizacji wywo a metody sumArray() polega zatem na ich umieszczeniu
w bloku synchronized. Ilustruje to wersja programu przedstawiona na listingu 11.9.
Listing 11.9. Sync2.java
// U ywa bloku synchronized
// dla synchronizacji dost pu
// do metody sumArray.
class SumArray {
private int sum;
Poleć książkę
Kup książkę
Rozdzia 11. Programowanie wielow tkowe 385
int sumArray(int nums[]) { W tym wypadku dost p do metody sumArray()
sum = 0; // zeruje sum nie podlega synchronizacji.
for(int i=0; i
sum += nums[i];
System.out.println(Thread.currentThread().getName() +
" wyliczy sum cz ciow równ " + sum);
try {
Thread.sleep(10); // umo liwia prze czenie w tków
}
catch(InterruptedException exc) {
System.out.println("W tek zosta przerwany.");
}
}
return sum;
}
}
class MyThread implements Runnable {
Thread thrd;
static SumArray sa = new SumArray();
int a[];
int answer;
// Tworzy nowy w tek.
MyThread(String name, int nums[]) {
thrd = new Thread(this, name);
a = nums; [ Pobierz całość w formacie PDF ]