IDZ DO PRZYK ADOWY ROZDZIA KATALOG KSI EK ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK CENNIK I INFORMACJE ZAMÓW INFORMACJE O NOWOŒCIACH ZAMÓW CENNIK CZYTELNIA SPIS TREŒCI KATALOG ONLINE DODAJ DO KOSZYKA FRAGMENTY KSI EK ONLINE Java. Æwiczenia zaawansowane Autor: Marcin Lis ISBN: 83-7197-947-9 Format: B5, stron: 142 Æwiczenia zaawansowane s¹ kolejnym etapem na drodze doskonalenia informatycznych umiejêtnoœci. Czytelnicy, którzy poznali poprzedni¹ ksi¹ k¹ Marcina Lisa Java. Æwiczenia praktyczne, z ca³¹ pewnoœci¹ nie bêd¹ zawiedzeni. Z niniejszej publikacji dowiemy siê, jak pisaæ programy wielow¹tkowe i jak w Javie obs³ugiwaæ bazy danych. Napiszemy w³asny, gotowy do praktycznego u ycia czat oraz aplikacjê do wysy³ania SMS-ów. Nauczymy siê te tworzyæ aplikacje sieciowe z interfejsem graficznym! Wybrane zagadnienia: W¹tki i programowanie wspó³bie ne w Javie Synchronizacja w¹tków Programowanie sieciowe Czym s¹ gniazda? Serwer wielow¹tkowy ¹czenie z baz¹ danych Dodawanie rekordów Modyfikacja rekordów w bazie Obs³uga transakcji i wartoœci null Aplikacja z interfejsem graficznym Ksi¹ ka otwiera now¹ seriê wydawnicz¹, której g³ównym zadaniem bêdzie poszerzenie uzyskanych wiadomoœci. Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl
Wstęp...z...z...... 5 Rozdział 1. Wątki i programowanie współbieżne w Javie...z... 7 Klasa Thread...d...d... 7 Interfejs Runnable...d...d. 11 Synchronizacja wątków...d... 17 Rozdział 2. Programowanie sieciowe...z......29 Czym są gniazda?...d...d. 29 Gniazda w Javie...d...d... 30 Klient i serwer...d...d... 35 Transmisja danych...d...d 39 Serwer wielowątkowy...d... 49 Rozdział 3. Aplikacje sieciowe z interfejsem graficznym...z... 63 Prawdziwa aplikacja czat (chat) w Javie...d... 63 Chat Serwer...d...d... 77 Wyślij SMS...d...d... 88 Idea...d...d... 92 Rozdział 4. Bazy danych...z...z..... 97 Łączenie z bazą danych...d... 97 Dodawanie rekordów...d... 106 Modyfikacja rekordów w bazie...d... 112 Obsługa transakcji i wartości null...d... 120 Aplikacja z interfejsem graficznym...d... 126
Ćwiczenie 1.1. Wątki w Javie reprezentowane są przez klasę $6/+., znajdującą się w pakiecie +:++21. Program korzystający z więcej niż jednego wątku możemy utworzyć na dwa sposoby. Albo wyprowadzimy własną, nową klasę z klasy $6/+., albo też nasza klasa będzie musiała implementować interfejs "922+,/. Zajmijmy się na początku metodą pierwszą. Utworzymy dwie klasy: klasę główną np. +2 i klasę rozszerzającą klasę $6/+. np. $6/+.. W klasie $6/+. należy zdefiniować metodę 692, od której rozpocznie się działanie wątku; w klasie +2 trzeba utworzyć obiekt klasy $6/+. i wywołać jego metodę 78+68. Najlepiej wykonać od razu odpowiedni przykład. Napisz kod klasy $6/+. dziedziczącej z klasy $6/+.. 49,- -+77$6/+./8/2.7$6/+. 49,-$6/+. 794/6 49,-:3.692 #78/39846282$6/+.$6/+.
8 Java. Ćwiczenia zaawansowane Ćwiczenie 1.2. Napisz kod klasy +2 tworzący wątek $6/+.. 49,--+77+2 49,-78+8-:3.+2#8621+617 $6/+.$6/+.2/;$6/+. $6/+.78+68 #78/39846282$6/+.+2 Rysunek 1.1. Wyraźnie widać, że oba wątki zostały wykonane Jeśli spojrzymy teraz na rysunek 1.1, przekonamy się, że oba wątki faktycznie zostały wykonane. Podobny efekt możemy osiągnąć również w nieco inny sposób. Nie trzeba tworzyć oddzielnie klasy uruchomieniowej dla wątku (w naszym przypadku była to klasa +2). Wystarczy w klasie wyprowadzonej z $6/+. zdefiniować metodę +2 i tam utworzyć obiekty wątków. Ćwiczenie 1.3. Napisz kod klasy $6/+. wyprowadzonej z klasy $6/+., uruchamiającej dwa przykładowe wątki. 49,- -+77$6/+./8/2.7$6/+. 49,-$6/+. 794/6 49,-:3.692 #78/398462821/8+/ 49,-78+8-:3.+2#8621+617 2/;$6/+.78+68 2/;$6/+.78+68
Rozdział 1. L Wątki i programowanie współbieżne w Javie 9 Rysunek 1.2. Na ekranie wyświetlone zostały systemowe nazwy wątków Efekt działania kodu z ćwiczenia 1.3 widoczny jest na rysunku 1.2. Na ekranie wyświetlone są nazwy wątków nadane im przez system. Wykorzystaliśmy w tym celu metodę 1/8+/ klasy $6/+.. Warto zauważyć, że w tej chwili mamy inną sytuację niż w poprzednich przykładach. W ćwiczeniach 1.1 i 1.2 występowały dwa wątki, wątek główny i wątek klasy $6/+.. Teraz mamy trzy wątki wątek główny, którego wykonanie rozpoczyna się od metody +2, oraz dwa wątki tworzone przez nas w tej metodzie, których wykonywanie rozpoczyna się od metody 692. Ćwiczenie 1.4. Gdybyśmy chcieli samodzielnie nadać nazwy poszczególnym wątkom, możemy nazwy te przekazać jako parametr w konstruktorze klasy $6/+., a następnie skorzystać z metody 7/8+/. Zmodyfikuj kod z ćwiczenia 1.3 w taki sposób, aby istniała możliwość nadania własnych nazw wątkom. 49,- -+77$6/+./8/2.7$6/+. 49,-$6/+.#86212+/ 794/6 7/8+/2+/ 49,-:3.692 #78/398462821/8+/ 49,-78+8-:3.+2#8621+617 2/;$6/+.'8/78+68 2/;$6/+.'8/78+68 Spróbujmy jednak przekonać się, że rzeczywiście nasze wątki wykonują się niezależnie od siebie. Wystarczy, jeśli dopiszemy pętlę wyświetlającą kilkukrotnie nazwę każdego wątku.
10Java. Ćwiczenia zaawansowane Ćwiczenie 1.5. Napisz przykładowy kod ilustrujący niezależne działanvie wątków. 49,- -+77$6/+./8/2.7$6/+. 28./+ 49,-$6/+.#86212+/Г28./+ 794/6 7/8+/2+/ 87./+./+ 49,-:3.692 03628 #78/398462821/8+/ 86 7//4./+ -+8-28/66948/.-/4832/ 49,-78+8-:3.+2#8621+617 2/;$6/+. /6;7Г78+68 2/;$6/+.691Г78+68 Rysunek 1.3. Widać wyraźnie, że wątki wykonują się niezależnie od siebie Dodatkowo wyposażyliśmy nasze wątki w metodę 7//4, która usypia je na zadaną ilość milisekund. Dzięki temu możemy spowodować, że każdy z nich wypisuje dane na ekran z inną prędkością. Efekt różnych prędkości działania widać wyraźnie na rysunku 1.3.
Rozdział 1. L Wątki i programowanie współbieżne w Javie 11 Wyprowadzanie własnej klasy z klasy $6/+. jest wygodne, ale nie zawsze możliwe. Z sytuacją taką będziemy mieli do czynienia, gdy nasza klasa już dziedziczy z innej, a musimy uzupełnić ją o możliwość działania wielowątkowego. Na szczęście istnieje interfejs "922+,/, który pomoże nam w rozwiązaniu tego problemu. W interfejsie "922+,/ zdefiniowana jest jedna metoda: 692, od której, podobnie jak w przypadku klasy $6/+., rozpoczyna się wykonywanie kodu wątku. W celu uruchomienia nowego wątku tworzymy nowy obiekt naszej klasy, a następnie używamy go jako parametru konstruktora klasy $6/+.. Schematycznie wygląda to następująco (zakładając, że +77 implementuje "922+,/): +77+77$6/+.2/;+77 2/;$6/+.+77$6/+. Dostępne konstruktory klasy $6/+. przedstawione są w tabeli 1.1. Tabela 1.1. Konstruktory klasy Thread Konstruktor $6/+. $6/+."922+,/8+61/8 $6/+."922+,/8+61/8Г #86212+/ $6/+.#86212+/ $6/+.$6/+.639416394Г "922+,/8+61/8 $6/+.$6/+.639416394Г "922+,/8+61/8Г#86212+/ $6/+.$6/+.639416394Г #86212+/ Opis Konstruktor bezparametrowy. Tworzy nowy obiekt klasby $6/+. Tworzy nowy obiekt klasy $6/+. związany z obiektem docelowym 8+61/8 Tworzy nowy obiekt klasy $6/+. związany z obiektem docelowym 8+61/8, o nazwie 2+/ Tworzy nowy obiekt klasy $6/+. o nazwie 2+/ Tworzy nowy obiekt klasy $6/+. związany z obiektem docelowym 8+61/8, przypisany do grupy 16394 Tworzy nowy obiekt klasy $6/+. o nazwie 2+/, związany z obiektem docelowym 8+61/8, przypisany do grupy 16394 Tworzy nowy obiekt klasy $6/+. o nazwie 2+/, przypisany do grupy 16394 Ćwiczenie 1.6. Napisz przykładowy kod ilustrujący niezależne działanie wątków. Skorzystaj z interfejsu "922+,/. 49,- -+77+24//287"922+,/ 28./+ #8621;36. 49,-+2#8621;36.Г28./+ 87./+./+ 87;36.;36.
12 Java. Ćwiczenia zaawansowane 49,-:3.692 03628 #78/39846282;36. 86 $6/+.7//4./+ -+8-28/66948/.-/4832/ 49,-78+8-:3.+2#8621+617 "922+,/86/+.2/;+286/+.Г "922+,/86/+.2/;+286/+.Г 2/;$6/+.86/+.78+68 2/;$6/+.86/+.78+68 Ćwiczenie 1.7. Dobrym przykładem wykorzystania interfejsu "922+,/ jest klasa posiadająca interfejs graficzny. Nie możemy w takim przypadku dziedziczyć bezpośrednio z klasy $6/+., gdyż np. utworzenie okna wymaga dziedziczenia z klasy 6+/, a wielodziedziczenia w Javie nie ma. Stosujemy więc interfejs "922+,/, który rozwiązuje nasz problem. Postarajmy się zatem napisać prostą aplikację z interfejsem graficznym, która będzie wykonywała przykładowe obliczenia w osobnym wątku. Napisz aplikację z interfejsem graficznym, wykonującą w osobnym wątku przykładowe obliczenia. Stan obliczeń powinien być sygnalizowany uvżytkownikowi. 4368+:++;8 4368+:++;8/:/28 49,- -+77+2/8/2.76+/4//287"922+,/Г-83278/2/6Г'2.3;78/2/6 46:+8/#8621;-$6/+. 4638/-8/.78+8-98832,#8+68 4638/-8/.78+8-98832,#834 4638/-8/.78+8-+,/ 6316/77 4638/-8/.78+8-,33/+278344/. 49,-+2#8621;-$6/+. 794/6 87;-$6/+.;-$6/+. 0+2/59+7;-$6/+. 6/8962 +..'2.3;78/2/687 7/8+39829 7/8#/Г,#8+682/;98832#8+68,#8+687/8392.7ГГГ
Rozdział 1. L Wątki i programowanie współbieżne w Javie 13,#8+68+..-83278/2/687 +..,#8+68,#8342/;98832#834,#8347/8392.7ГГГ,#834+..-83278/2/687 +..,#834 6316/772/;+,/ 6316/777/8392.7ГГГ +.. 6316/77,#8+687/82+,/.869/,#8347/82+,/.0+7/ 7/8&7,/869/ 49,-:3.692 78344/.0+7/ 03628 86 $6/+.7//4 -+8-28/66948/.-/4832/ 078344/.,6/+ 6316/777/8$/828/1/683#8621,#8+687/82+,/.869/,#8347/82+,/.0+7/ 49,-78+8-:3.+2#8621+617 2/;+2+2 49,-:3.+-832 /6036/.-832:/28/:8 #862184/:81/8-8323+2. 084/59+7#8+68,#8+687/82+,/.0+7/ +2+22/;+2-3498/ 2/;$6/+.+278+68,#8347/82+,/.869/ /7/084/59+7#834 78344/.869/ 49,-:3.;2.3;/-320/.'2.3;:/28/:8 49,-:3.;2.3;37/.'2.3;:/28/:8 49,-:3.;2.3;/+-8:+8/.'2.3;:/28/:8
14 Java. Ćwiczenia zaawansowane 49,-:3.;2.3;3721'2.3;:/28/:8 #78//8 49,-:3.;2.3;-8:+8/.'2.3;:/28/:8 49,-:3.;2.3;-320/.'2.3;:/28/:8 49,-:3.;2.3;4/2/.'2.3;:/28/:8 Rysunek 1.4. Po kliknięciu przycisku Start rozpoczęły się obliczenia Ćwiczenie 1.8. W metodzie 692 napisaliśmy zwykłą pętlę 036 symulującą wykonywanie jakichś obliczeń. Co 250 milisekund uaktualnia ona tekst etykiety 6316/77. Wykonywanie tej operacji rozpoczyna się po naciśnięciu przycisku Start. Działanie pętli możemy przerwać poprzez wciśnięcie przycisku Stop, następuje wtedy przypisanie zmiennej 78344/. wartości 869/. Wartość tej zmiennej sprawdzana jest cyklicznie, zatem po takim przypisaniu nastąpi przerwanie działania. Musimy tutaj zdawać sobie jednak sprawę, że mamy dwa obiekty klasy +2. Jeden z nich tworzony jest w metodzie +2, drugi po naciśnięciu przycisku Start. Zatem jeśli mają one ze sobą współpracować na takiej zasadzie jak przedstawiona powyżej, zmienne,#8+68,,#834, 6316/77 i 78344/. muszą być zadeklarowane jako statyczne. Inaczej każdy wątek będzie operował na własnej, lokalnej kopii tych zmiennych i całość oczywiście nie będzie działać. Nic nie stoi jednak na przveszkodzie, aby aplikację tę skonstruować w taki sposób, aby wątek był tworzony znanym nam już sposobem, przez oddzielną klasę, pochodną od $6/+.. Napisz kod klasy $6/+. symulującej wykonywanie obliczeń i współpracującej z klasą +2 realizującą interfejs graficzny. 49,- -+77$6/+./8/2.7$6/+. 28./+ +24+6/28,33/+278344/. 49,-$6/+.+24+6/28Г28./+
Rozdział 1. L Wątki i programowanie współbieżne w Javie 15 794/6 87./+./+ 874+6/284+6/28 49,-:3.692 78344/.0+7/ 03628 86 7//4./+ -+8-28/66948/.-/4832/ 078344/.,6/+ 4+6/28 6316/777/8$/828/1/683#8621 Ćwiczenie 1.9. Metoda 692 wygląda tu bardzo podobnie, jak w poprzednim ćwiczeniu. Różnice są takie, że opóźnienie jest teraz sparametryzowane, możemy je regulować wartością zmiennej./+ (jest ona przekazywana w konstruktorze klasy) oraz że wprowadziliśmy zmienną 4+6/28, która jest referencją do obiektu klasy +2 i umożliwia nam komunikację z nim. Dzięki temu możemy modyfikować tekst pojawiający się na ekranie. Musimy w tej chwili tylko przystosować klasę +2 do współpracy z naszym nowym wątkiem. Napisz kod klasy +2 wykorzystującej przygotowaną w ćwiczeniu 1.8 klasę vwątku. 4368+:++;8 4368+:++;8/:/28 49,- -+77+2/8/2.76+/4//287-83278/2/6Г'2.3;78/2/6 4638/-8/.98832,#8+68 4638/-8/.98832,#834 4638/-8/.+,/ 6316/77 4638/-8/.$6/+.86/+. 49,-+2 794/6 +..'2.3;78/2/687 7/8+39829 7/8#/Г,#8+682/;98832#8+68,#8+687/8392.7ГГГ,#8+68+..-83278/2/687 +..,#8+68
16 Java. Ćwiczenia zaawansowane,#8342/;98832#834,#8347/8392.7ггг,#834+..-83278/2/687 +..,#834 6316/772/;+,/ 6316/777/8392.7ГГГ +.. 6316/77,#8+687/82+,/.869/,#8347/82+,/.0+7/ 7/8&7,/869/ 49,-78+8-:3.+2#8621+617 2/;+2 49,-:3.+-832 /6036/.-832:/28/:8 #862184/:81/8-8323+2. 084/59+7#8+68,#8+687/82+,/.0+7/ 86/+.2/;$6/+.87Г 86/+.78+68,#8347/82+,/.869/ /7/084/59+7#834 86/+.78344/.869/,#8+687/82+,/.869/,#8347/82+,/.0+7/ 49,-:3.;2.3;/-320/.'2.3;:/28/:8 49,-:3.;2.3;37/.'2.3;:/28/:8 49,-:3.;2.3;/+-8:+8/.'2.3;:/28/:8 49,-:3.;2.3;3721'2.3;:/28/:8 #78//8 49,-:3.;2.3;-8:+8/.'2.3;:/28/:8 49,-:3.;2.3;-320/.'2.3;:/28/:8 49,-:3.;2.3;4/2/.'2.3;:/28/:8
Rozdział 1. L Wątki i programowanie współbieżne w Javie 17 Ćwiczenie 1.10. Rozważmy w tej chwili następującą sytuację: mamy zmienną typu całkowitego i dwa wątki modyfikujące jej wartość. Załóżmy, że będzie to dodawanie w pętli w każdym przebiegu wartości 1, a sama pętla będzie miała tych przebiegów 10. Jaka będzie ostateczna wartość naszej zmiennej? Jeśli pierwszy wątek 10 razy zwiększył wartość o 1 i drugi wątek zrobił to samo, to w sumie powinno dać 20. Napiszmy taki program. Napisz program, w którym dwa wątki będą niezależnie od siebie modyfikowały wartość jednej zmiennej typu 28. 49,- -+77$6/+./8/2.7$6/+. 46:+8/28;-$6/+. 46:+8/28./+ 46:+8/78+8-28+--3928 49,-$6/+.28;-$6/+.Г28./+ 794/6 87./+./+ 87;-$6/+.;-$6/+. 49,-:3.692 7;8-;-$6/+. -+7/86/+.,6/+ -+7/86/+.,6/+ -+7/86/+.,6/+ 49,-78+8-:3.+2#8621+617 2/;$6/+.Г78+68 2/;$6/+.Г78+68 2/;$6/+.Г78+68 49,-:3.86/+. 03628 86 7//4./+ -+8-28/66948/.-/4832/ +--3928 49,-:3.86/+. 03628 86 7//4./+
18 Java. Ćwiczenia zaawansowane -+8-28/66948/.-/4832/ +--3928 49,-72-632/.:3.86/+. 86 ;+8 -+8-28/66948/.-/4832/ #78/39846282/ #78/398462821/8+/+--3928 Ćwiczenie 1.11. Wątki 86/+. i 86/+. zajmują się zwiększaniem wartości zmiennej +--3928. Jedynym zadaniem wątku 86/+. jest odczekanie 1 000 milisekund i wyświetlenie wartości zmiennej +--3928. Uruchomienie powyższego kodu wykaże, że faktycznie otrzymamy wartość 20, tak jak przewidzieliśmy wcześniej. Czy zatem wszystko jest w porządku? Jak najbardziej. Co się jednak stanie, jeśli instrukcja modyfikująca +--3928 będzie w postaci +--3928 +--3928? Napiszmy taki program. Zmodyfikuj kod z ćwiczenia 1.10 w taki sposób, aby modyfikacja zmiennej +--3928 była w postaci: +--3928+--3928. 49,- -+77$6/+./8/2.7$6/+. 46:+8/28;-$6/+. 46:+8/28./+ 46:+8/78+8-28+--3928 49,-$6/+.28;-$6/+.Г28./+ 794/6 87./+./+ 87;-$6/+.;-$6/+. 49,-:3.692 7;8-;-$6/+. -+7/86/+.,6/+ -+7/86/+.,6/+ -+7/86/+.,6/+ 49,-78+8-:3.+2#8621+617 2/;$6/+.Г78+68 2/;$6/+.Г78+68 2/;$6/+.Г78+68
Rozdział 1. L Wątki i programowanie współbieżne w Javie 19 49,-:3.86/+. 03628 86 7//4./+ -+8-28/66948/.-/4832/ +--3928+--3928 49,-:3.86/+. 03628 86 7//4./+ -+8-28/66948/.-/4832/ +--3928+-3-928 49,-72-632/.:3.86/+. 86 ;+8 -+8-28/66948/.-/4832/ #78/39846282/ #78/398462821/8+/+--3928 Modyfikacje nie były duże, a po uruchomieniu ujrzymy prawdopodobnie również wynik 20. Czy zatem wszystko znowu jest w porządku? Otóż absolutnie nie! Wszystko zależy teraz od kompilatora. Jeśli jest on inteligentny, prawdopodobnie potraktuje instrukcję +--3928 +--3928 jako +--3928. W takim wypadku faktycznie program będzie prawidłowy, gdyż +--3928 jest instrukcją atomową, tzn. nie może być ona przerwana przez inny wątek. Niestety nie należy przyjmować takiego założenia, natomiast trzeba traktować taki kod jako złożenie następujących operacji: L pobranie wartości +--3928, L dodanie do tej wartości 1, L zapisanie otrzymanej wartości do zmiennej +--3928. Skoro tak, operacje te mogą zostać przerwane przez inny wątek. Co się wtedy stanie? Otóż otrzymany wynik na pewno nie będzie prawidłowy. Żeby się o tym przekonać, zasymulujemy przerywanie tych operacji. Zrobimy to w sposób następujący: L wartość zmiennej +--3928 będziemy modyfikować w dwóch krokach, L pomiędzy poszczególnymi operacjami dodamy instrukcjvę 7//4, usypiającą dany wątek.
20Java. Ćwiczenia zaawansowane Ćwiczenie 1.12. Kod w każdym wątku powinien zatem wyglądać następujvąco: 288/4 03628 8/4+--3928 86 7//4./+ -+8-28/66948/.-/4832/ +--39288/4 #78/398462821/8+/+--3928 Napisz program wymuszający wzajemne przerywanie pracy wątków przy modyfikacji wspólnej zmiennej typu 28. 49,- -+77$6/+./8/2.7$6/+. 46:+8/28;-$6/+. 46:+8/28./+ 46:+8/78+8-28+--3928 49,-$6/+.28;-$6/+.Г28./+ 794/6 87./+./+ 87;-$6/+.;-$6/+. 49,-:3.692 7;8-;-$6/+. -+7/86/+.,6/+ -+7/86/+.,6/+ -+7/86/+.,6/+ 49,-78+8-:3.+2#8621+617 2/;$6/+.Г78+68 2/;$6/+.Г78+68 2/;$6/+.Г78+68 49,-:3.86/+. 288/4 03628 8/4+--3928 86 7//4./+ -+8-28/66948/.-/4832/ +--39288/4 #78/398462821/8+/+--3928
Rozdział 1. L Wątki i programowanie współbieżne w Javie 21 49,-:3.86/+. 288/4 03628 8/4+--3928 86 7//4./+ -+8-28/66948/.-/4832/ +--39288/4 #78/398462821/8+/+--3928 49,-72-632/.:3.86/+. 86 ;+8 -+8-28/66948/.-/4832/ #78/39846282/ #78/398462821/8+/+--3928 Rysunek 1.5. Widać wyraźnie, że wątki sobie wzajemnie przeszkadzają Instrukcje #78/39846282 dokładnie pokazują nam, co się dzieje. Wynik oczywiście nie jest prawidłowy, gdyż pomiędzy pobraniem wartości +--3928 a jej modyfikacją i ponownym zapisaniem w każdym wątku występuje przerwa, umożliwiająca wykonanie operacji przez inny wątek. Skutek jest taki, że mówiąc potocznie nie wie lewica, co robi prawica i wynik jest zafałszowany. Jest to typowy przykład dostępu do zasobu współdzielonego przez pracujące współbieżnie wątki. Aby zatem nasz przykład był poprawny, musimy dokonać ich synchronizacji. W Javie służy do tego instrukcja 72-632/.. Możemy ją stosować zarówno w przypadku metod (ang. synchronized methods), jak i obiektów. Jeżeli zadeklarujemy metodę jako 72-632/., np.:
22 Java. Ćwiczenia zaawansowane Ćwiczenie 1.13. 49,-72-632/.:3.73; 27869-/ to wywołanie takiej metody powoduje zablokowanie obiektu, na rzecz którego jest ona wywoływana. Obiekt ten będzie zablokowany, aż do zakończenia wykonywania tejże instrukcji i inne wątki nie będą miały do niego dostępu. Druga metoda to zablokowanie obiektu w postaci: #2-632/.3,/8 27869-/ przy czym obiekt użyty do synchronizacji nie musi być użyty w bloku instrukcji. Spróbujmy zatem zsynchronizować dostęp do zmiennej +--3928 z poprzedniego ćwiczenia. Dokonaj synchronizacji dostępu do zmiennej +--3928 z ćwiczenia 1.12. 49,- -+77$6/+./8/2.7$6/+. 46:+8/28;-$6/+. 46:+8/28./+ 46:+8/78+8-28+--3928 46:+8/78+8-,/-87/+436/ 49,-$6/+.28;-$6/+.Г28./+ 794/6 87./+./+ 87;-$6/+.;-$6/+. 49,-:3.692 7;8-;-$6/+. -+7/86/+.,6/+ -+7/86/+.,6/+ -+7/86/+.,6/+ 49,-78+8-:3.+2#8621+617 7/+436/2/;,/-8 2/;$6/+.Г78+68 2/;$6/+.Г78+68 2/;$6/+.Г78+68 49,-:3.86/+. 288/4 03628 72-632/.7/+436/ 8/4+--3928
Rozdział 1. L Wątki i programowanie współbieżne w Javie 23 86 7//4./+ -+8-28/66948/.-/4832/ +--39288/4 #78/398462821/8+/+--3928 49,-:3.86/+. 288/4 03628 72-632/.7/+436/ 8/4+--3928 86 7//4./+ -+8-28/66948/.-/4832/ +--39288/4 #78/398462821/8+/+--3928 49,-72-632/.:3.86/+. 86 ;+8 -+8-28/66948/.-/4832/ #78/39846282/ #78/398462821/8+/+--3928 Na rysunku 1.6 widać, że synchronizacja zakończyła się pełnym powodzeniem. Użyliśmy dodatkowego obiektu 7/+436/, który pełni rolę strażnika dostępu do zmiennej +--3928. Jest to jego jedyna rola, do niczego innego nam w tym przykładzie nie służy. Oczywiście nic nie stoi na przeszkodzie, aby użyć obiektu, który jest wykorzystywany w kodzie programu, np. tablicy, jednakże w powyższym ćwiczeniu po prostu nie mieliśmy takiego pod ręką. Nie możemy natomiast użyć w tym celu zmiennej +--3928 (wszak to byłoby najwygodniejsze), gdyż jest ona typu 28, a instrukcji 72-632/. możemy użyć tylko w stosunku do typów wyprowadzonych z klasy,/-8. Pokażmy jednak, że do synchronizacji można użyć obiektu, który będzie modyfikowany. Nie musimy wtedy wprowadzać dodatkowej zmiennej synchronizacyjnej. Aby tego dokonać, musimy napisać własną klasę enkapsulującą zmienną typu 28. To zadanie powinno być zupełnie banalne.
24 Java. Ćwiczenia zaawansowane Rysunek 1.6. Synchronizacja powiodła się i otrzymany wynik jest teraz prawidłowy Ćwiczenie 1.14. Napisz kod klasy --3928 enkapsulującej zmienną typu 28. 49,- -+77--3928 49,-28:+9/ Ćwiczenie 1.15. Dokonaj synchronizacji dostępu do zmiennej +--3928 z ćwiczenia 1.12. Nie używaj dodatkowego obiektu klasy,/-8. Zamiast tego zmień typ +--3928 z 28 na --3928 i użyj tego obiektu do synchronizacji. 49,- -+77$6/+./8/2.7$6/+. 46:+8/28;-$6/+. 46:+8/28./+ 46:+8/78+8---3928+--3928 49,-$6/+.28;-$6/+.Г28./+ 794/6 87./+./+ 87;-$6/+.;-$6/+. 49,-:3.692 7;8-;-$6/+. -+7/86/+.,6/+ -+7/86/+.,6/+ -+7/86/+.,6/+ 49,-78+8-:3.+2#8621+617 +--39282/;--3928 2/;$6/+.Г78+68
Rozdział 1. L Wątki i programowanie współbieżne w Javie 25 2/;$6/+.Г78+68 2/;$6/+.Г78+68 49,-:3.86/+. 288/4 03628 72-632/.+--3928 8/4+--3928:+9/ 86 7//4./+ -+8-28/66948/.-/4832/ +--3928:+9/8/4 #78/398462821/8+/+--3928:+9/ 49,-:3.86/+. 288/4 03628 72-632/.+--3928 8/4+--3928:+9/ 86 7//4./+ -+8-28/66948/.-/4832/ +--3928:+9/8/4 #78/398462821/8+/+--3928:+9/ 49,-72-632/.:3.86/+. 86 ;+8 -+8-28/66948/.-/4832/ #78/39846282/ #78/398462821/8+/+--3928:+9/ Jak widać, obiektem służącym do synchronizacji jest tu +--3928 i jednocześnie jest to obiekt, który modyfikujemy w bloku 72-632/.. Jest to bardzo wygodna metoda, gdyż nie musimy tworzyć dodatkowych zmiennych zaśmiecającyvch system. Skorzystajmy teraz z drugiego sposobu synchronizacji, czyli z metod synchronizowanych. Zgodnie z tym, co napisaliśmy powyżej, musimy utworzyć metodę, która będzie modyfikowała obiekt --3928 i zadeklarować ją jako 72-632/.. Może ona wyglądać w sposób następujący:
26 Java. Ćwiczenia zaawansowane Ćwiczenie 1.16. 49,-78+8-72-632/.:3.94.+8/--3928 288/4+--3928:+9/ +--3928:+9/8/4 Pozostaje teraz wykorzystać ten kod w aplikacji. Dokonaj synchronizacji dostępu do zmiennej typu --3928. Wykorzystaj synchronizowaną metodę 94.+8/--3928. 49,- -+77$6/+./8/2.7$6/+. 46:+8/28;-$6/+. 46:+8/28./+ 46:+8/78+8---3928+--3928 49,-$6/+.28;-$6/+.Г28./+ 794/6 87./+./+ 87;-$6/+.;-$6/+. 49,-:3.692 7;8-;-$6/+. -+7/86/+.,6/+ -+7/86/+.,6/+ -+7/86/+.,6/+ 49,-78+8-:3.+2#8621+617 +--39282/;--3928 2/;$6/+.Г78+68 2/;$6/+.Г78+68 2/;$6/+.Г78+68 49,-78+8-72-632/.:3.94.+8/--3928 288/4+--3928:+9/ +--3928:+9/8/4 49,-:3.86/+. 03628 94.+8/--3928 #78/398462821/8+/+--3928:+9/ 86 7//4./+ -+8-28/66948/.-/4832/
Rozdział 1. L Wątki i programowanie współbieżne w Javie 27 49,-:3.86/+. 03628 94.+8/--3928 #78/398462821/8+/+--3928:+9/ 86 7//4./+ -+8-28/66948/.-/4832/ 49,-72-632/.:3.86/+. 86 ;+8 -+8-28/66948/.-/4832/ #78/39846282/ #78/398462821/8+/+--3928:+9/