Tytuł oryginału: Java, A Beginner's Guide, 5th Edition
Tłumaczenie: Jaromir Senczyk
ISBN: 978-83-246-3919-9
Original edition copyright © 2012 by The McGraw-Hill Companies, Inc.
All rights reserved.
Polish edition copyright © 2012 by HELION SA
All rights reserved.
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording or by any information storage retrieval system,
without permission from the Publisher.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną,
fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich
właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były
kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane
z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie
ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji
zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Pliki z przykładami omawianymi w książce można znaleźć pod adresem:
ftp://ftp.helion.pl/przyklady/javpp5.zip
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/javpp5
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Printed in Poland.
Spis treci
O autorze ................................................................................................. 11
O redaktorze technicznym ........................................................................ 11
Wstp ...................................................................................................... 13
Rozdzia 1. Podstawy Javy ......................................................................................... 19
Pochodzenie Javy ........................................................................................................................20
Java a jzyki C i C++ ............................................................................................................21
Java a C# ...............................................................................................................................22
Java a Internet ..............................................................................................................................22
Aplety Java ............................................................................................................................22
Bezpieczestwo .....................................................................................................................23
Przenono ...........................................................................................................................23
Magiczny kod bajtowy ................................................................................................................24
Terminologia Javy .......................................................................................................................25
Programowanie obiektowe ..........................................................................................................26
Hermetyzacja .........................................................................................................................27
Polimorfizm ...........................................................................................................................28
Dziedziczenie ........................................................................................................................28
Java Development Kit .................................................................................................................29
Pierwszy prosty program .............................................................................................................30
Wprowadzenie tekstu programu ............................................................................................30
Kompilowanie programu .......................................................................................................31
Pierwszy program wiersz po wierszu ....................................................................................31
Obsuga bdów skadni ...............................................................................................................34
Drugi prosty program ..................................................................................................................35
Inne typy danych .........................................................................................................................37
Przykad 1.1. Zamiana galonów na litry ......................................................................................38
Dwie instrukcje sterujce .............................................................................................................39
Instrukcja if ...........................................................................................................................40
Ptla for .................................................................................................................................41
Bloki kodu ...................................................................................................................................43
rednik i pozycja kodu w wierszu ...............................................................................................44
Wcicia ........................................................................................................................................45
Przykad 1.2. Ulepszony konwerter galonów na litry ..................................................................45
Sowa kluczowe jzyka Java .......................................................................................................46
Identyfikatory ..............................................................................................................................47
Biblioteki klas ..............................................................................................................................48
Test sprawdzajcy .......................................................................................................................48
Kup książkę
Poleć książkę
4
Java. Przewodnik dla pocztkujcych
Rozdzia 2. Typy danych i operatory ............................................................................ 49
Dlaczego typy danych s tak wane ............................................................................................50
Typy podstawowe ........................................................................................................................50
Typy cakowite ......................................................................................................................51
Typy zmiennoprzecinkowe ...................................................................................................52
Znaki .....................................................................................................................................53
Typ logiczny ................................................................................................................................54
Przykad 2.1. Jak daleko uderzy piorun? ....................................................................................55
Literay ........................................................................................................................................56
Literay szesnastkowe, ósemkowe i binarne ..........................................................................57
Specjalne sekwencje znaków ................................................................................................57
Literay acuchowe ..............................................................................................................58
Zmienne .......................................................................................................................................59
Inicjalizacja zmiennej ............................................................................................................59
Dynamiczna inicjalizacja ......................................................................................................60
Zasig deklaracji i czas istnienia zmiennych ...............................................................................60
Operatory .....................................................................................................................................63
Operatory arytmetyczne ..............................................................................................................63
Inkrementacja i dekrementacja ..............................................................................................65
Operatory relacyjne i logiczne .....................................................................................................66
Warunkowe operatory logiczne ...................................................................................................67
Operator przypisania ....................................................................................................................69
Skrótowe operatory przypisania ..................................................................................................69
Konwersje typów w instrukcjach przypisania .............................................................................71
Rzutowanie typów niezgodnych ..................................................................................................72
Priorytet operatorów ....................................................................................................................74
Przykad 2.2. Tabela prawdy dla operatorów logicznych ............................................................74
Wyraenia ....................................................................................................................................75
Konwersja typów w wyraeniach ..........................................................................................76
Odstpy i nawiasy .................................................................................................................77
Test sprawdzajcy .......................................................................................................................78
Rozdzia 3. Instrukcje sterujce ................................................................................. 79
Wprowadzanie znaków z klawiatury ...........................................................................................79
Instrukcja if ..................................................................................................................................81
Zagniedanie instrukcji if ..........................................................................................................82
Drabinka if-else-if .......................................................................................................................83
Instrukcja switch ..........................................................................................................................84
Zagniedanie instrukcji switch ...................................................................................................88
Przykad 3.1. Rozpoczynamy budow systemu pomocy .............................................................88
Ptla for .......................................................................................................................................90
Wariacje na temat ptli for ..........................................................................................................92
Brakujce elementy .....................................................................................................................93
Ptla nieskoczona ................................................................................................................94
Ptle bez ciaa ..............................................................................................................................94
Deklaracja zmiennych sterujcych wewntrz ptli ......................................................................95
Rozszerzona ptla for ..................................................................................................................96
Ptla while ...................................................................................................................................96
Ptla do-while ..............................................................................................................................97
Przykad 3.2. Ulepszamy system pomocy ...................................................................................99
Przerywanie ptli instrukcj break .............................................................................................102
Zastosowanie break jako formy goto .........................................................................................104
Zastosowanie instrukcji continue ...............................................................................................108
Przykad 3.3. Kocowa wersja systemu pomocy .......................................................................109
Poleć książkę
Kup książkę
Spis treci
5
Ptle zagniedone ....................................................................................................................112
Test sprawdzajcy .....................................................................................................................113
Rozdzia 4. Wprowadzenie do klas, obiektów i metod ................................................ 115
Podstawy klas ............................................................................................................................116
Ogólna posta klasy ............................................................................................................116
Definiowanie klasy ..............................................................................................................117
Jak powstaj obiekty ..................................................................................................................120
Referencje obiektów i operacje przypisania ..............................................................................120
Metody ......................................................................................................................................121
Dodajemy metod do klasy Vehicle ....................................................................................122
Powrót z metody ........................................................................................................................124
Zwracanie wartoci ....................................................................................................................125
Stosowanie parametrów .............................................................................................................127
Dodajemy sparametryzowan metod do klasy Vehicle .....................................................128
Przykad 4.1. System pomocy jako klasa ...................................................................................130
Konstruktory ..............................................................................................................................135
Konstruktory z parametrami ......................................................................................................136
Dodajemy konstruktor do klasy Vehicle ....................................................................................137
Operator new .............................................................................................................................138
Odzyskiwanie nieuytków i metoda finalize() ...........................................................................139
Metoda finalize() .......................................................................................................................139
Przykad 4.2. Ilustracja dziaania odzyskiwania nieuytków i metody finalize() ......................140
Sowo kluczowe this ..................................................................................................................142
Test sprawdzajcy .....................................................................................................................144
Rozdzia 5. Wicej typów danych i operatorów .......................................................... 145
Tablice .......................................................................................................................................145
Tablice jednowymiarowe ....................................................................................................146
Przykad 5.1. Sortowanie tablicy ...............................................................................................149
Tablice wielowymiarowe ..........................................................................................................151
Tablice dwuwymiarowe ......................................................................................................151
Tablice nieregularne ..................................................................................................................152
Tablice o trzech i wicej wymiarach ...................................................................................153
Inicjalizacja tablic wielowymiarowych ...............................................................................153
Alternatywna skadnia deklaracji tablic .....................................................................................155
Przypisywanie referencji tablic ..................................................................................................155
Wykorzystanie skadowej length ...............................................................................................156
Przykad 5.2. Klasa Queue .........................................................................................................158
Styl for-each ptli for .................................................................................................................162
Iteracje w tablicach wielowymiarowych .............................................................................165
Zastosowania rozszerzonej ptli for ....................................................................................166
acuchy znaków ......................................................................................................................167
Tworzenie acuchów ..........................................................................................................167
Operacje na acuchach .......................................................................................................168
Tablice acuchów ...............................................................................................................170
acuchy s niezmienne .....................................................................................................171
acuchy sterujce instrukcj switch ..................................................................................172
Wykorzystanie argumentów wywoania programu ...................................................................173
Operatory bitowe .......................................................................................................................175
Operatory bitowe AND, OR, XOR i NOT ..........................................................................175
Operatory przesunicia ........................................................................................................179
Skrótowe bitowe operatory przypisania ..............................................................................181
Przykad 5.3. Klasa ShowBits ...................................................................................................182
Poleć książkę
Kup książkę
6
Java. Przewodnik dla pocztkujcych
Operator ? ..................................................................................................................................184
Test sprawdzajcy .....................................................................................................................186
Rozdzia 6. Wicej o metodach i klasach .................................................................. 189
Kontrola dostpu do skadowych klasy .....................................................................................189
Modyfikatory dostpu w Javie ............................................................................................190
Przykad 6.1. Ulepszamy klas Queue .......................................................................................194
Przekazywanie obiektów metodom ...........................................................................................195
Sposób przekazywania argumentów ...................................................................................196
Zwracanie obiektów ..................................................................................................................199
Przecianie metod ....................................................................................................................201
Przecianie konstruktorów .......................................................................................................205
Przykad 6.2. Przeciamy konstruktor klasy Queue .................................................................207
Rekurencja .................................................................................................................................210
Sowo kluczowe static ...............................................................................................................212
Bloki static ..........................................................................................................................215
Przykad 6.3. Algorytm Quicksort .............................................................................................216
Klasy zagniedone i klasy wewntrzne ....................................................................................218
Zmienne liczby argumentów .....................................................................................................221
Metody o zmiennej liczbie argumentów ..............................................................................222
Przecianie metod o zmiennej liczbie argumentów ...........................................................225
Zmienna liczba argumentów i niejednoznaczno ..............................................................226
Test sprawdzajcy .....................................................................................................................227
Rozdzia 7. Dziedziczenie ......................................................................................... 229
Podstawy dziedziczenia .............................................................................................................230
Dostp do skadowych a dziedziczenie ......................................................................................232
Konstruktory i dziedziczenie .....................................................................................................235
Uycie sowa kluczowego super do wywoania konstruktora klasy bazowej ............................237
Uycie sowa kluczowego super do dostpu do skadowych klasy bazowej .............................240
Przykad 7.1. Tworzymy hierarchi klas Vehicle ......................................................................241
Wielopoziomowe hierarchie klas ...............................................................................................244
Kiedy wywoywane s konstruktory? ........................................................................................247
Referencje klasy bazowej i obiekty klasy pochodnej .................................................................248
Przesanianie metod ...................................................................................................................252
Przesanianie metod i polimorfizm ............................................................................................255
Po co przesania metody? ........................................................................................................257
Zastosowanie przesaniania metod w klasie TwoDShape ...................................................257
Klasy abstrakcyjne .....................................................................................................................260
Sowo kluczowe final ................................................................................................................264
final zapobiega przesanianiu ..............................................................................................264
final zapobiega dziedziczeniu ..............................................................................................265
Uycie final dla zmiennych skadowych .............................................................................265
Klasa Object ..............................................................................................................................267
Test sprawdzajcy .....................................................................................................................268
Rozdzia 8. Pakiety i interfejsy ................................................................................. 269
Pakiety .......................................................................................................................................269
Definiowanie pakietu ..........................................................................................................270
Wyszukiwanie pakietów i zmienna CLASSPATH ..............................................................271
Prosty przykad pakietu .......................................................................................................272
Pakiety i dostp do skadowych .................................................................................................273
Przykad dostpu do pakietu ................................................................................................274
Skadowe protected ...................................................................................................................275
Import pakietów .........................................................................................................................277
Poleć książkę
Kup książkę
Spis treci
7
Biblioteka klas Java uywa pakietów ........................................................................................279
Interfejsy ....................................................................................................................................279
Implementacje interfejsów .........................................................................................................281
Referencje interfejsu ..................................................................................................................284
Przykad 8.1. Tworzymy interfejs Queue ..................................................................................286
Zmienne w interfejsach .............................................................................................................290
Interfejsy mog dziedziczy ......................................................................................................291
Test sprawdzajcy .....................................................................................................................293
Rozdzia 9. Obsuga wyjtków .................................................................................. 295
Hierarchia wyjtków ..................................................................................................................296
Podstawy obsugi wyjtków ......................................................................................................296
Sowa kluczowe try i catch ..................................................................................................297
Prosty przykad wyjtku ......................................................................................................298
Konsekwencje nieprzechwycenia wyjtku ................................................................................300
Wyjtki umoliwiaj obsug bdów .................................................................................301
Uycie wielu klauzul catch ..................................................................................................302
Przechwytywanie wyjtków klas pochodnych ..........................................................................303
Zagniedanie bloków try .........................................................................................................304
Generowanie wyjtku ................................................................................................................305
Powtórne generowanie wyjtku ..........................................................................................306
Klasa Throwable ........................................................................................................................307
Klauzula finally .........................................................................................................................309
Uycie klauzuli throws ..............................................................................................................311
Nowoci w JDK 7 ......................................................................................................................312
Wyjtki wbudowane w Jav ......................................................................................................313
Tworzenie klas pochodnych wyjtków ......................................................................................315
Przykad 9.1. Wprowadzamy wyjtki w klasie Queue ...............................................................317
Test sprawdzajcy .....................................................................................................................320
Rozdzia 10. Obsuga wejcia i wyjcia ....................................................................... 323
Strumienie wejcia i wyjcia .....................................................................................................324
Strumienie bajtowe i strumienie znakowe .................................................................................324
Klasy strumieni bajtowych ........................................................................................................325
Klasy strumieni znakowych .......................................................................................................326
Strumienie predefiniowane ........................................................................................................326
Uywanie strumieni bajtowych .................................................................................................327
Odczyt wejcia konsoli ........................................................................................................328
Zapis do wyjcia konsoli .....................................................................................................329
Odczyt i zapis plików za pomoc strumieni bajtowych .............................................................330
Odczyt z pliku .....................................................................................................................330
Zapis w pliku .......................................................................................................................334
Automatyczne zamykanie pliku .................................................................................................336
Odczyt i zapis danych binarnych ...............................................................................................339
Przykad 10.1. Narzdzie do porównywania plików .................................................................341
Pliki o dostpie swobodnym ......................................................................................................343
Strumienie znakowe ..................................................................................................................345
Odczyt konsoli za pomoc strumieni znakowych ................................................................345
Obsuga wyjcia konsoli za pomoc strumieni znakowych .................................................349
Obsuga plików za pomoc strumieni znakowych .....................................................................350
Klasa FileWriter ..................................................................................................................350
Klasa FileReader .................................................................................................................351
Zastosowanie klas opakowujcych do konwersji acuchów numerycznych ............................352
Przykad 10.2. System pomocy wykorzystujcy pliki ...............................................................355
Test sprawdzajcy .....................................................................................................................361
Poleć książkę
Kup książkę
8
Java. Przewodnik dla pocztkujcych
Rozdzia 11. Programowanie wielowtkowe ................................................................ 363
Podstawy wielowtkowoci .......................................................................................................364
Klasa Thread i interfejs Runnable .............................................................................................365
Tworzenie wtku .......................................................................................................................365
Drobne usprawnienia ...........................................................................................................369
Przykad 11.1. Tworzymy klas pochodn klasy Thread ...........................................................370
Tworzenie wielu wtków ...........................................................................................................372
Jak ustali, kiedy wtek zakoczy dziaanie? ...........................................................................375
Priorytety wtków .....................................................................................................................378
Synchronizacja ..........................................................................................................................380
Synchronizacja metod ................................................................................................................381
Synchronizacja instrukcji ..........................................................................................................384
Komunikacja midzywtkowa ...................................................................................................386
Przykad uycia metod wait() i notify() ...............................................................................387
Wstrzymywanie, wznawianie i koczenie dziaania wtków ....................................................392
Przykad 11.2. Wykorzystanie gównego wtku ........................................................................396
Test sprawdzajcy .....................................................................................................................397
Rozdzia 12. Typy wyliczeniowe, automatyczne opakowywanie,
import skadowych statycznych i adnotacje ............................................. 399
Wyliczenia .................................................................................................................................400
Podstawy wylicze ..............................................................................................................400
Wyliczenia s klasami ...............................................................................................................403
Metody values() i valueOf() ......................................................................................................403
Konstruktory, metody, zmienne instancji a wyliczenia .............................................................404
Dwa wane ograniczenia .....................................................................................................406
Typy wyliczeniowe dziedzicz po klasie Enum ........................................................................406
Przykad 12.1. Komputerowo sterowana sygnalizacja wietlna ................................................408
Automatyczne opakowywanie ...................................................................................................413
Typy opakowujce .....................................................................................................................413
Podstawy automatycznego opakowywania ................................................................................415
Automatyczne opakowywanie i metody ....................................................................................416
Automatyczne opakowywanie i wyraenia ................................................................................418
Przestroga ............................................................................................................................419
Import skadowych statycznych .................................................................................................420
Adnotacje (metadane) ................................................................................................................422
Test sprawdzajcy .....................................................................................................................425
Rozdzia 13. Generyczno ......................................................................................... 427
Podstawy generycznoci ............................................................................................................428
Prosty przykad generycznoci ..................................................................................................428
Generyczno dotyczy tylko obiektów ................................................................................432
Typy generyczne róni si dla rónych argumentów .........................................................432
Klasa generyczna o dwóch parametrach ..............................................................................433
Ogólna posta klasy generycznej ........................................................................................434
Ograniczanie typów ...................................................................................................................434
Stosowanie argumentów wieloznacznych .................................................................................438
Ograniczanie argumentów wieloznacznych ...............................................................................440
Metody generyczne ...................................................................................................................443
Konstruktory generyczne ...........................................................................................................445
Interfejsy generyczne .................................................................................................................445
Przykad 13.1. Generyczna klasa Queue ....................................................................................448
Typy surowe i tradycyjny kod ...................................................................................................452
Wnioskowanie typów i operator diamentowy ...........................................................................455
Wymazywanie ...........................................................................................................................456
Poleć książkę
Kup książkę
Spis treci
9
Bdy niejednoznacznoci .........................................................................................................457
Ograniczenia zwizane z generycznoci ..................................................................................458
Zakaz tworzenia instancji parametru okrelajcego typ ......................................................458
Ograniczenia dla skadowych statycznych ..........................................................................458
Ograniczenia tablic generycznych .......................................................................................459
Ograniczenia zwizane z wyjtkami ...................................................................................460
Dalsze studiowanie zagadnienia generycznoci .........................................................................460
Test sprawdzajcy .....................................................................................................................461
Rozdzia 14. Aplety, zdarzenia i pozostae sowa kluczowe .......................................... 463
Podstawy apletów ......................................................................................................................464
Organizacja apletów i podstawowe elementy ............................................................................467
Architektura apletu ....................................................................................................................467
Kompletny szkielet apletu .........................................................................................................468
Rozpoczcie i zakoczenie dziaania apletu ..............................................................................469
danie odrysowania .................................................................................................................470
Metoda update() ..................................................................................................................471
Przykad 14.1. Prosty aplet wywietlajcy baner .......................................................................471
Wykorzystanie okna statusu ......................................................................................................475
Parametry apletów .....................................................................................................................475
Klasa Applet ..............................................................................................................................477
Obsuga zdarze ........................................................................................................................479
Model delegacji zdarze ............................................................................................................479
Zdarzenia ...................................................................................................................................479
róda zdarze .....................................................................................................................479
Suchacze zdarze ...............................................................................................................480
Klasy zdarze ......................................................................................................................480
Interfejsy suchaczy zdarze ................................................................................................480
Wykorzystanie modelu delegacji zdarze ..................................................................................481
Obsuga zdarze myszy .......................................................................................................482
Prosty aplet obsugujcy zdarzenia myszy ..........................................................................483
Inne sowa kluczowe Javy .........................................................................................................486
Modyfikatory transient i volatile .........................................................................................486
Operator instanceof .............................................................................................................486
Sowo kluczowe strictfp ......................................................................................................487
Sowo kluczowe assert ........................................................................................................487
Metody natywne ..................................................................................................................488
Test sprawdzajcy .....................................................................................................................490
Rozdzia 15. Wprowadzenie do Swing ......................................................................... 491
Pochodzenie i filozofia Swing ...................................................................................................492
Komponenty i kontenery ...........................................................................................................494
Komponenty ........................................................................................................................494
Kontenery ............................................................................................................................495
Panele kontenerów szczytowych .........................................................................................495
Menedery ukadu .....................................................................................................................496
Pierwszy program wykorzystujcy Swing .................................................................................497
Pierwszy program Swing wiersz po wierszu .......................................................................498
Komponent JButton ...................................................................................................................502
Komponent JTextField ..............................................................................................................506
Komponent JCheckBox .............................................................................................................509
Komponent JList .......................................................................................................................512
Przykad 15.1. Porównywanie plików — aplikacja Swing ........................................................516
Wykorzystanie anonimowych klas wewntrznych do obsugi zdarze .....................................521
Aplety Swing .............................................................................................................................522
Poleć książkę
Kup książkę
10
Java. Przewodnik dla pocztkujcych
Co dalej? ....................................................................................................................................524
Test sprawdzajcy .....................................................................................................................525
Dodatek A
Rozwizania testów sprawdzajcych ....................................................... 527
Rozdzia 1. Podstawy Javy ........................................................................................................527
Rozdzia 2. Typy danych i operatory .........................................................................................529
Rozdzia 3. Instrukcje sterujce .................................................................................................531
Rozdzia 4. Wprowadzenie do klas, obiektów i metod ..............................................................533
Rozdzia 5. Wicej typów danych i operatorów ........................................................................535
Rozdzia 6. Wicej o metodach i klasach ..................................................................................538
Rozdzia 7. Dziedziczenie .........................................................................................................543
Rozdzia 8. Pakiety i interfejsy ..................................................................................................545
Rozdzia 9. Obsuga wyjtków ..................................................................................................546
Rozdzia 10. Obsuga wejcia i wyjcia .....................................................................................549
Rozdzia 11. Programowanie wielowtkowe .............................................................................552
Rozdzia 12. Typy wyliczeniowe, automatyczne opakowywanie,
import skadowych statycznych i adnotacje ..........................................................554
Rozdzia 13. Generyczno .......................................................................................................558
Rozdzia 14. Aplety, zdarzenia i pozostae sowa kluczowe ......................................................562
Rozdzia 15. Wprowadzenie do Swing ......................................................................................567
Dodatek B Komentarze dokumentacyjne .................................................................. 573
Znaczniki javadoc ......................................................................................................................573
@author ...............................................................................................................................574
{@code} ..............................................................................................................................575
@deprecated ........................................................................................................................575
{@docRoot} ........................................................................................................................575
@exception .........................................................................................................................575
{@inheritDoc} ....................................................................................................................575
{@link} ...............................................................................................................................575
{@linkplain} .......................................................................................................................576
{@literal} ............................................................................................................................576
@param ...............................................................................................................................576
@return ...............................................................................................................................576
@see ....................................................................................................................................576
@serial ................................................................................................................................577
@serialData .........................................................................................................................577
@serialField ........................................................................................................................577
@since .................................................................................................................................577
@throws ..............................................................................................................................577
{@value} .............................................................................................................................578
@version .............................................................................................................................578
Ogólna posta komentarza dokumentacyjnego ..........................................................................578
Wynik dziaania programu javadoc ...........................................................................................579
Przykad uycia komentarzy dokumentacyjnych .......................................................................579
Skorowidz .............................................................................................. 581
Poleć książkę
Kup książkę
Rozdzia 11.
Programowanie
wielowtkowe
W tym rozdziale poznasz:
podstawy wielowtkowoci,
klas
Thread
i interfejs
Runnable
,
tworzenie wtku,
tworzenie wielu wtków,
sposób ustalania zakoczenia wtku,
korzystanie z priorytetów wtków,
synchronizacj wtków,
synchronizacj metod,
synchronizacj bloków,
komunikacj midzywtkow,
wstrzymywanie, wznawianie i koczenie dziaania wtków.
Chocia Java dostarcza programistom wielu innowacyjnych moliwoci, to z pewnoci jedn
z najbardziej ekscytujcych jest obsuga programowania wielowtkowego. Program wie-
lowtkowy zawiera dwie lub wicej czci, które mog dziaa równolegle. Kad z tych
czci nazywamy wtkiem, a kady wtek definiuje osobn ciek wykonania. Wielowtko-
wo jest zatem szczególn form wielozadaniowoci.
Poleć książkę
Kup książkę
364
Java. Przewodnik dla pocztkujcych
Podstawy wielowtkowoci
Istniej dwa podstawowe typy wielozadaniowoci, z których jeden opiera si na procesach,
a drugi wykorzystuje wtki. Wane jest, aby zrozumia rónice midzy nimi. Proces odpo-
wiada w zasadzie wykonywanemu programowi. Zatem wielozadaniowo wykorzystujca
procesy umoliwia Twojemu komputerowi równolege wykonywanie dwóch lub wicej pro-
gramów. Wykorzystanie procesów umoliwi Ci na przykad uruchomienie kompilatora Javy
w tym samym czasie, gdy piszesz kod ródowy w edytorze lub przegldasz strony w Internecie.
W przypadku wielozadaniowoci wykorzystujcej procesy program jest najmniejsz jednostk
kodu podlegajc szeregowaniu do wykonania przez procesor.
W drugim rodzaju wielozadaniowoci najmniejsz jednostk kodu szeregowan przez system
jest wtek. Oznacza to, e pojedynczy program moe równoczenie wykonywa dwa lub wicej
wtków. Na przykad edytor tekstu moe w tym samym czasie formatowa jeden tekst i dru-
kowa inny, pod warunkiem e obie akcje s wykonywane przez osobne wtki. Chocia Java
wykorzystuje rodowiska wielozadaniowe oparte na procesach, to nie umoliwia sterowania
ich dziaaniem. W przypadku wtków sprawy maj si inaczej.
Podstawow zalet wielowtkowoci jest moliwo tworzenia efektywnie dziaajcych pro-
gramów, poniewa wielowtkowo pozwala wykorzysta okresy bezczynnoci pojawiajce
si w dziaaniu wikszoci programów. Wikszo urzdze wejcia i wyjcia takich jak porty
sieciowe, napdy dyskowe czy klawiatura dziaa znacznie wolniej od procesora. Z tego powodu
program czsto spdza wiele czasu na oczekiwaniu na moliwo wysania lub odebrania
danych za porednictwem urzdzenia. Zastosowanie wielowtkowoci pozwala programowi
wykonywa w tym czasie inne zadania. Na przykad w czasie gdy jedna cz programu wysya
plik w Internecie, inna moe zajmowa si odczytem klawiatury, a jeszcze inna buforowa
kolejny blok wysyanych danych.
W ostatnich kilku latach mamy do czynienia z upowszechnieniem si systemów wieloproce-
sorowych i wielordzeniowych. Oczywicie nie wypary one zupenie systemów jednoproceso-
rowych. Wielowtkowo w Javie moe dziaa w obu typach systemów. W przypadku sys-
temu jednordzeniowego wykonywane równolegle wtki wspódziel procesor i kady wtek
otrzymuje pewien przedzia czasu procesora. Zatem w systemie jednordzeniowym dwa lub
wicej wtków nie jest w rzeczywistoci wykonywanych równoczenie, ale ich zastosowanie
pozwala wykorzysta czas bezczynnoci procesora. Natomiast w systemach wieloproceso-
rowych bd wielordzeniowych wtki rzeczywicie mog dziaa równolegle. W wielu przy-
padkach pozwala to jeszcze bardziej poprawi efektywno dziaania programu i zwikszy
szybko wykonywania niektórych operacji.
Wtek moe znajdowa si w jednym z kilku stanów. Moe by wykonywany. Moe by
gotowy do wykonywania, gdy tylko otrzyma czas procesora. Wykonanie wtku moe zosta
zawieszone, co oznacza, e wtek nie jest wykonywany przez pewien czas. Jego wykonywanie
moe zosta póniej podjte. Wtek moe zosta zablokowany w oczekiwaniu na zwolnienie
pewnego zasobu. I wreszcie wykonywanie wtku moe zosta zakoczone, co oznacza, e
nie mona ju go podj.
Wielowtkowo wie si nierozerwalnie z pojciem synchronizacji, która umoliwia skoor-
dynowane dziaanie wielu wtków. Java dysponuje kompletnym podsystemem synchronizacji.
Jego podstawowe moliwoci równie omówi w tym rozdziale.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
365
Jeli programowae ju na przykad w systemie Windows, to by moe masz pewne pojcie
o wielowtkowoci. Java umoliwia zarzdzanie wtkami za pomoc odpowiednich elementów
jzyka, co czyni programowanie wielowtkowe szczególnie wygodnym, poniewa wiele jego
szczegóów Java obsuguje za Ciebie.
Klasa Thread i interfejs Runnable
Wielowtkowo w Javie bazuje na klasie
Thread
i towarzyszcym jej interfejsie
Runnable
,
które umieszczono w pakiecie
java.lang
. Klasa
Thread
hermetyzuje wtek. Jeli chcesz stwo-
rzy w programie nowy wtek, powiniene utworzy obiekt klasy pochodnej klasy
Thread
albo zaimplementowa interfejs
Runnable
.
Klasa
Thread
definiuje szereg metod pomagajcych zarzdza wtkami. Najczciej uywane
z tych metod przedstawiem w tabeli 11.1 (przyjrzymy si im bliej podczas ich uycia
w przykadach).
Tabela 11.1.
Wybrane metody klasy Thread
Metoda
Znaczenie
final String getName( )
Zwraca nazw wtku.
final int getPriority( )
Zwraca priorytet wtku.
final boolean isAlive( )
Sprawdza, czy wtek jest nadal wykonywany.
final void join( )
Czeka na zakoczenie wtku.
void run( )
Punkt wejcia wtku.
static void sleep(long milisekund)
Zawiesza wykonywanie wtku na podan liczb
milisekund
.
void start( )
Rozpoczyna wykonywanie wtku przez wywoanie metody
run( )
.
Wszystkie procesy maj przynajmniej jeden wtek wykonania, zwykle nazywany wtkiem
gównym, poniewa jego wykonanie rozpoczyna si w momencie uruchomienia programu.
Moemy zatem powiedzie, e we wszystkich dotychczasowych przykadach uywalimy
wtku gównego. W wtku gównym moesz tworzy kolejne wtki programu.
Tworzenie wtku
Wtek powstaje przez utworzenie obiektu typu
Thread
. Klasa
Thread
hermetyzuje obiekt, który
moe by wykonywany. Jak ju wspomniaem, Java umoliwia dwa sposoby tworzenia takich
obiektów:
poprzez implementacj interfejsu
Runnable
,
poprzez tworzenie klas pochodnych klasy
Thread
.
W wikszoci przykadów w tym rozdziale bdziemy implementowa interfejs
Runnable
.
Natomiast w przykadzie 11.1 zademonstruj, jak zaimplementowa wtek, tworzc klas
Poleć książkę
Kup książkę
366
Java. Przewodnik dla pocztkujcych
pochodn klasy
Thread
. Zapamitaj: oba podejcia i tak uywaj klasy
Thread
do tworzenia
wtku i zarzdzania nim. Jedyna rónica polega na sposobie, w jaki powstaje klasa reprezentu-
jca wtki.
Interfejs
Runnable
stanowi abstrakcj wykonywalnego kodu. Wtek moesz utworzy na
podstawie kadego obiektu, który implementuje interfejs
Runnable
. Interfejs ten ma tylko jedn
metod o nazwie
run()
zadeklarowan w nastpujcy sposób:
public void run()
Wewntrz metody
run()
umieszczasz kod wykonywany przez nowy wtek. Podobnie jak
gówny wtek programu, tak i metoda
run()
moe wywoywa inne metody, uywa innych
klas i deklarowa zmienne. Jedyna rónica polega na tym, e metoda
run()
jest punktem
wejcia do osobnego, równolegle wykonywanego wtku programu. Wykonywanie tego wtku
koczy si, gdy metoda
run()
zwróci sterowanie.
Po utworzeniu klasy implementujcej interfejs
Runnable
na podstawie jej obiektu tworzysz
obiekt typu
Thread
. Klasa
Thread
definiuje szereg konstruktorów. Na pocztek bdziemy
uywa poniszego:
Thread(Runnable obWtku)
W tym przypadku parametr
obWtku
jest instancj klasy implementujcej interfejs
Runnable
.
Definiuje on punkt, w którym rozpocznie si wykonywanie nowego wtku.
Po utworzeniu nowy wtek nie bdzie wykonywany, dopóki nie wywoasz jego metody
start()
zadeklarowanej w klasie
Thread
. Dziaanie metody
start()
sprowadza si w zasadzie
do wywoania metody
run()
. Poniej przedstawiem deklaracj metody
start()
:
void start()
Na listingu 11.1 przedstawiem przykad programu, który tworzy nowy wtek i rozpoczyna
jego wykonywanie.
Listing 11.1.
UseThreads.java
// Tworzy wtek, implementujc interfejs Runnable.
class MyThread implements Runnable {
String thrdName;
MyThread(String name) {
thrdName = name;
}
// Punkt wejciowy wtku.
public void run() {
Tutaj rozpoczyna si wykonywanie wtku.
System.out.println(thrdName + " rozpoczyna dziaanie.");
try {
for(int count=0; count < 10; count++) {
Thread.sleep(400);
System.out.println(thrdName +
" jest wykonywany, warto licznika: " + count);
}
}
Obiekty klasy
MyThread mog by
wykonywane we wasnych wtkach,
poniewa klasa
MyThread implementuje
interfejs
Runnable.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
367
catch(InterruptedException exc) {
System.out.println(thrdName + " zosta przerwany.");
}
System.out.println(thrdName + " koczy dziaanie.");
}
}
class UseThreads {
public static void main(String args[]) {
System.out.println("Gówny wtek rozpoczyna dziaanie.");
// Najpierw tworzy obiekt klasy MyThread.
MyThread mt = new MyThread("Wtek potomny nr 1");
// Nastpnie na jego podstawie tworzy wtek.
Thread newThrd = new Thread(mt);
Tworzy wtek dla tego obiektu.
// Na koniec rozpoczyna wykonywanie wtku.
newThrd.start();
Uruchamia wtek.
for(int i=0; i<50; i++) {
System.out.print(".");
try {
Thread.sleep(100);
}
catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
}
System.out.println("Wtek gówny koczy dziaanie.");
}
}
Przyjrzyjmy si bliej temu programowi. Najpierw klasa
MyThread
implementuje interfejs
Runnable
. Oznacza to, e obiekt typu
MyThread
moe zosta przekazany konstruktorowi klasy
i by wykonywany we wasnym wtku.
Wewntrz metody
run()
dziaa ptla
for
odliczajca od 0 do 9. Zwró uwag na wywoanie
metody
sleep()
. Metoda
sleep()
powoduje zawieszenie wtku, w którym zostaa wywoana,
na czas wyraony w milisekundach. Jej deklaracj przedstawiem poniej:
static void sleep(long milisekund) throwws InterruptedException
Wykonywanie wtku zostaje zawieszone na czas
milisekund
. Metoda
sleep()
moe wygene-
rowa wyjtek
InterruptedException
i wobec tego musi by wywoywana w bloku
try
.
Metoda
sleep()
ma równie drug wersj, która umoliwia okrelenie czasu zawieszenia
wtku z dokadnoci nie tylko co do milisekundy, ale równie nanosekundy, jeli potrzebu-
jesz a takiej precyzji. W naszym przykadzie metoda
sleep()
wywoywana przez metod
run()
zawiesza wykonywanie wtku na 400 milisekund podczas kadego przebiegu ptli.
Dziki temu spowolnieniu moemy obserwowa wykonywanie wtku.
Wewntrz metody
main()
nowy obiekt typu
Thread
zostaje utworzony na skutek wykonania
poniszej sekwencji instrukcji:
Tworzy obiekt
implementujcy
interfejs
Runnable.
Poleć książkę
Kup książkę
368
Java. Przewodnik dla pocztkujcych
// Najpierw tworzy obiekt klasy MyThread.
MyThread mt = new MyThread("Wtek potomny nr 1");
// Nastpnie na jego podstawie tworzy wtek.
Thread newThrd = new Thread(mt);
// Na koniec rozpoczyna wykonywanie wtku.
newThrd.start();
Jak sugeruj to komentarze, najpierw zostaje utworzony obiekt klasy
MyThread
. Obiekt ten
zostaje nastpnie uyty do stworzenia obiektu typu
Thread
. Jest to moliwe, poniewa klasa
MyThread
implementuje interfejs
Runnable
. Na koniec wykonywanie nowego wtku rozpo-
czyna si dziki wywoaniu metody
start()
. Wywouje ona metod
run()
nowego wtku.
Po wywoaniu metody
start()
sterowanie powraca do metody
main()
, która rozpoczyna
wykonywanie wasnej ptli
for
. Ptla ta wykonywana jest 50 razy i w kadym przebiegu zawie-
sza wykonanie gównego wtku na 100 milisekund. Oba wtki kontynuuj swoje dziaanie,
wspódzielc procesor (w systemie jednoprocesorowym). Trwa to a do momentu, w którym
zakoczy si dziaanie wykonywanych przez nie ptli. Komunikaty wywietlane przez oba
wtki przedstawiem poniej. Ze wzgldu na rónice w rodowisku wykonania programu
efekt jego dziaania w Twoim przypadku moe si nieco róni.
Gówny wtek rozpoczyna dziaanie.
.Wtek potomny nr 1 rozpoczyna dziaanie.
....Wtek potomny nr 1 jest wykonywany, warto licznika: 0
...Wtek potomny nr 1 jest wykonywany, warto licznika: 1
....Wtek potomny nr 1 jest wykonywany, warto licznika: 2
....Wtek potomny nr 1 jest wykonywany, warto licznika: 3
....Wtek potomny nr 1 jest wykonywany, warto licznika: 4
....Wtek potomny nr 1 jest wykonywany, warto licznika: 5
....Wtek potomny nr 1 jest wykonywany, warto licznika: 6
....Wtek potomny nr 1 jest wykonywany, warto licznika: 7
....Wtek potomny nr 1 jest wykonywany, warto licznika: 8
....Wtek potomny nr 1 jest wykonywany, warto licznika: 9
Wtek potomny nr 1 koczy dziaanie.
..........Wtek gówny koczy dziaanie.
W przykadzie tym warto zwróci uwag na jeszcze jedn rzecz. Aby zilustrowa fakt rów-
noczesnego wykonywania wtku gównego i wtku
mt
, musiaem unikn zakoczenia dzia-
ania metody
main()
, zanim wtek
mt
zakoczy swoje dziaanie. W tym celu wykorzystaem
rónice czasowe w dziaaniu obu wtków. Poniewa wywoania metody
sleep()
w ptli
for
metody
main()
powoduj cakowite opónienie równe 5 sekund (50 iteracji po 100 sekund
kada), a cakowite opónienie wewntrz ptli
for
metody
run()
wynosi jedynie 4 sekundy
(10 iteracji po 400 milisekund kada), metoda
run()
zakoczy dziaanie sekund wczeniej
ni metoda
main()
. W efekcie wtek gówny i wtek
mt
s wykonywane równolegle do momentu
zakoczenia wtku
mt
. Wykonywanie wtku gównego (metody
main()
) koczy si sekund
póniej.
Chocia wykorzystanie rónic czasowych pozwolio mi zademonstrowa równolege dziaa-
nie wtków, rozwizania takiego nie stosuje si w praktyce. Java udostpnia znacznie lepsze
sposoby oczekiwania na zakoczenie wtku. Jeden z nich omówi w dalszej czci rozdziau.
I jeszcze jedno: w przypadku programów wielowtkowych najczciej bdziemy chcieli, aby
wtek gówny koczy swoje dziaanie jako ostatni. W ogólnym przypadku program dziaa,
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
369
dopóki nie zakoczy si wykonywanie wszystkich jego wtków. Zatem nie jest wymagane,
by wtek gówny koczy swoje dziaanie jako ostatni. Ale czsto jest to przykadem dobrej
praktyki programistycznej, zwaszcza gdy dopiero uczysz si korzystania z wtków.
Drobne usprawnienia
Chocia poprzedni program jest zupenie poprawny, niewielkie modyfikacje mog usprawni
jego dziaanie i uatwi jego uycie. Po pierwsze, moemy rozpocz wykonywanie wtku
natychmiast po jego utworzeniu. W tym celu tworzymy obiekt
Thread
wewntrz konstruktora
klasy
MyThread
. Po drugie, klasa
MyThread
nie musi przechowywa nazwy wtku, poniewa
moemy nada mu j podczas tworzenia. W tym celu uyjemy nastpujcej wersji konstruktora
klasy
Thread
:
Thread(Runnable obWtku, String nazwa)
W tym przypadku parametr
nazwa
okrela oczywicie nazw wtku.
Ekspert odpowiada
Pytanie: Dlaczego zalecasz, aby gówny wtek koczy dziaanie jako ostatni?
Odpowied: W starszych wersjach Javy zakoczenie dziaania gównego wtku przed zakoczeniem
dziaania wtku potomnego mogo powodowa bd dziaania maszyny wirtualnej. Nowoczesne wersje
Javy nie stwarzaj ju tego rodzaju problemów. Lepiej jednak zachowa ostrono, poniewa nigdy
nie wiemy, w jakim rodowisku przyjdzie dziaa naszemu programowi. Dodatkowo wtek gówny
jest doskonaym miejscem do wykonania operacji zwizanych z zakoczeniem dziaania programu,
na przykad zamknicia plików. Z tego powodu czsto rzeczywicie ma sens, aby koczy on swoje
dziaanie jako ostatni. Na szczcie bardzo atwo moemy zaprogramowa oczekiwanie wtku gów-
nego na zakoczenie dziaania wszystkich jego wtków potomnych.
Nazw wtku moemy uzyska, wywoujc metod
getName()
zdefiniowan w klasie
Thread
.
Jej ogóln posta przedstawiem poniej:
final String getName()
Chocia nie jest to konieczne, w naszym nastpnym programie moesz nada nazw wtkowi
po jego utworzeniu. W tym celu uyjesz metody
setName()
przedstawionej poniej:
final void setName(String nazwaWtku)
Ulepszon wersj poprzedniego programu przedstawiem na listingu 11.2.
Listing 11.2.
UseThreadsImproved.java
// Ulepszona wersja klasy MyThread.
class MyThread implements Runnable {
Thread thrd;
Zmienna
thrd przechowuje referencj wtku.
// Tworzy nowy wtek.
MyThread(String name) {
thrd = new Thread(this, name);
Wtek otrzymuje nazw w momencie utworzenia.
thrd.start(); // uruchamia nowy wtek
Uruchamia wtek.
Poleć książkę
Kup książkę
370
Java. Przewodnik dla pocztkujcych
}
// Rozpoczyna wykonywanie nowego wtku.
public void run() {
System.out.println(thrd.getName() + " rozpoczyna dziaanie.");
try {
for(int count=0; count<10; count++) {
Thread.sleep(400);
System.out.println(thrd.getName() +
" jest wykonywany, warto licznika: " + count);
}
}
catch(InterruptedException exc) {
System.out.println(thrd.getName() + " zosta przerwany.");
}
System.out.println(thrd.getName() + " koczy dziaanie.");
}
}
class UseThreadsImproved {
public static void main(String args[]) {
System.out.println("Gówny wtek rozpoczyna dziaanie.");
MyThread mt = new MyThread("Wtek potomny nr 1");
for(int i=0; i < 50; i++) {
Teraz wtek zostaje uruchomiony w momencie utworzenia.
System.out.print(".");
try {
Thread.sleep(100);
}
catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
}
System.out.println("Wtek gówny koczy dziaanie.");
}
}
Ta wersja programu wywietla takie same komunikaty jak poprzednia. Zwró uwag, e refe-
rencj wtku przechowuje skadowa
thrd
klasy
MyThread
.
Przykad 11.1.
Tworzymy klas pochodn klasy Thread
Implementacja interfejsu
Runnable
jest jednym ze sposobów tworzenia klasy
reprezentujcej wtki. Drugi sposób polega na utworzeniu klasy wtków jako
klasy pochodnej klasy
Thread
. W tym przykadzie utworzymy wanie klas pochodn klasy
Thread
i wykorzystamy j w programie, którego funkcjonalno bdzie odpowiada progra-
mowi
UseThreadsImproved
.
Tworzc klas pochodn klasy
Thread
, musimy przesoni jej metod
run()
stanowic punkt
wejcia do nowego wtku. Nowa klasa musi równie wywoa metod
start()
, aby rozpo-
cz wykonywanie nowego wtku. Moesz równie przesoni inne metody klasy
Thread()
, ale
nie jest to wymagane.
ExtendThread.java
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
371
1.
Utwórz plik o nazwie ExtendThread.java. Skopiuj do niego kod ródowy z pliku
UseThreadsImproved.java.
2.
Zmie deklaracj klasy
Thread
tak, aby zamiast implementowa interfejs
Runnable
,
dziedziczya po klasie
Thread
:
class MyThread extends Thread {
3.
Usu poniszy wiersz:
Thread thrd;
Zmienna skadowa
thrd
nie jest ju potrzebna, poniewa instancja klasy
MyThread
zawiera instancj klasy
Thread
, do której moe si odwoywa.
4.
Zmie konstruktor klasy
MyThread
w nastpujcy sposób:
// Tworzy nowy wtek.
MyThread(String name) {
super(name); // nazwa wtku
start(); // uruchamia wtek
}
Wywoanie
super
zostaje uyte w celu uruchomienia nastpujcego konstruktora
klasy
Thread
:
Thread(String nazwa)
gdzie parametr
nazwa
okrela oczywicie nazw tworzonego wtku.
5.
Zmie metod
run()
tak, aby bezporednio, czyli bez uycia zmiennej
thrd
, wywoywaa
metod
getName()
:
// Rozpoczyna wykonywanie nowego wtku.
public void run() {
System.out.println(getName() + " rozpoczyna dziaanie.");
try {
for(int count=0; count < 10; count++) {
Thread.sleep(400);
System.out.println(getName() +
" jest wykonywany, warto licznika: " + count);
}
}
catch(InterruptedException exc) {
System.out.println(getName() + " zosta przerwany.");
}
System.out.println(getName() + " zosta przerwany.");
}
6.
Na listingu 11.3 przedstawiem kompletny tekst ródowy programu, który w obecnej
wersji tworzy klas pochodn klasy
Thread
, zamiast implementowa interfejs
Runnable
.
Wynik dziaania wywietlany przez program bdzie taki sam jak w przypadku
poprzednich wersji programu.
Listing 11.3.
ExtendThread.java
/*
Przykad 11.1
Tworzy klas pochodn klasy Thread.
Poleć książkę
Kup książkę
372
Java. Przewodnik dla pocztkujcych
*/
class MyThread extends Thread {
// Tworzy nowy wtek.
MyThread(String name) {
super(name); // nazwa wtku
start(); // uruchamia wtek
}
// Rozpoczyna wykonywanie nowego wtku.
public void run() {
System.out.println(getName() + " rozpoczyna dziaanie.");
try {
for(int count=0; count < 10; count++) {
Thread.sleep(400);
System.out.println(getName() +
" jest wykonywany, warto licznika: " + count);
}
}
catch(InterruptedException exc) {
System.out.println(getName() + " zosta przerwany.");
}
System.out.println(getName() + " zosta przerwany.");
}
}
class ExtendThread {
public static void main(String args[]) {
System.out.println("Gówny wtek rozpoczyna dziaanie.");
MyThread mt = new MyThread("Wtek potomny nr 1");
for(int i=0; i < 50; i++) {
System.out.print(".");
try {
Thread.sleep(100);
}
catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
}
System.out.println("Wtek gówny koczy dziaanie.");
}
}
Tworzenie wielu wtków
W poprzednich przykadach tworzylimy tylko jeden wtek potomny. Nic nie stoi jednak na
przeszkodzie, aby Twój program tworzy dowoln, potrzebn liczb wtków. Program przed-
stawiony na listingu 11.4 tworzy trzy wtki potomne.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
373
Listing 11.4.
MoreThreads.java
// Tworzy wiele wtków.
class MyThread implements Runnable {
Thread thrd;
// Tworzy nowy wtek.
MyThread(String name) {
thrd = new Thread(this, name);
thrd.start(); // uruchamia wtek
}
// Rozpoczyna wykonywanie nowego wtku.
public void run() {
System.out.println(thrd.getName() + " rozpoczyna dziaanie.");
try {
for(int count=0; count < 10; count++) {
Thread.sleep(400);
System.out.println(thrd.getName() +
" jest wykonywany, warto licznika: " + count);
}
}
catch(InterruptedException exc) {
System.out.println(thrd.getName() + " zosta przerwany.");
}
System.out.println(thrd.getName() + " koczy dziaanie.");
}
}
class MoreThreads {
public static void main(String args[]) {
System.out.println("Gówny wtek rozpoczyna dziaanie.");
MyThread mt1 = new MyThread("Wtek potomny nr 1");
MyThread mt2 = new MyThread("Wtek potomny nr 2");
MyThread mt3 = new MyThread("Wtek potomny nr 3");
for(int i=0; i < 50; i++) {
System.out.print(".");
try {
Thread.sleep(100);
}
catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
}
System.out.println("Wtek gówny koczy dziaanie.");
}
}
A oto przykad dziaania tego programu:
Gówny wtek rozpoczyna dziaanie.
Wtek potomny nr 1 rozpoczyna dziaanie.
Tworzy i uruchamia
trzy wtki.
Poleć książkę
Kup książkę
374
Java. Przewodnik dla pocztkujcych
Wtek potomny nr 3 rozpoczyna dziaanie.
.Wtek potomny nr 2 rozpoczyna dziaanie.
...Wtek potomny nr 1 jest wykonywany, warto licznika: 0
Wtek potomny nr 3 jest wykonywany, warto licznika: 0
.Wtek potomny nr 2 jest wykonywany, warto licznika: 0
...Wtek potomny nr 1 jest wykonywany, warto licznika: 1
Wtek potomny nr 3 jest wykonywany, warto licznika: 1
.Wtek potomny nr 2 jest wykonywany, warto licznika: 1
...Wtek potomny nr 1 jest wykonywany, warto licznika: 2
Wtek potomny nr 3 jest wykonywany, warto licznika: 2
.Wtek potomny nr 2 jest wykonywany, warto licznika: 2
....Wtek potomny nr 3 jest wykonywany, warto licznika: 3
Wtek potomny nr 1 jest wykonywany, warto licznika: 3
Wtek potomny nr 2 jest wykonywany, warto licznika: 3
....Wtek potomny nr 3 jest wykonywany, warto licznika: 4
Wtek potomny nr 1 jest wykonywany, warto licznika: 4
Wtek potomny nr 2 jest wykonywany, warto licznika: 4
....Wtek potomny nr 3 jest wykonywany, warto licznika: 5
Wtek potomny nr 1 jest wykonywany, warto licznika: 5
Wtek potomny nr 2 jest wykonywany, warto licznika: 5
...Wtek potomny nr 3 jest wykonywany, warto licznika: 6
Wtek potomny nr 1 jest wykonywany, warto licznika: 6
.Wtek potomny nr 2 jest wykonywany, warto licznika: 6
...Wtek potomny nr 3 jest wykonywany, warto licznika: 7
Wtek potomny nr 1 jest wykonywany, warto licznika: 7
.Wtek potomny nr 2 jest wykonywany, warto licznika: 7
...Wtek potomny nr 1 jest wykonywany, warto licznika: 8
.Wtek potomny nr 3 jest wykonywany, warto licznika: 8
Wtek potomny nr 2 jest wykonywany, warto licznika: 8
...Wtek potomny nr 1 jest wykonywany, warto licznika: 9
Wtek potomny nr 1 koczy dziaanie.
.Wtek potomny nr 3 jest wykonywany, warto licznika: 9
Wtek potomny nr 3 koczy dziaanie.
Wtek potomny nr 2 jest wykonywany, warto licznika: 9
Wtek potomny nr 2 koczy dziaanie.
.........Wtek gówny koczy dziaanie.
Ekspert odpowiada
Pytanie: Dlaczego Java udostpnia dwa sposoby tworzenia wtków potomnych (przez tworzenie klas
pochodnych klasy Thread lub przez implementacj interfejsu Runnable) i który z nich jest lepszy?
Odpowied: Klasa
Thread definiuje szereg metod, które mog zosta przesonite w klasie pochod-
nej. Natomiast wymagane jest przesonicie tylko jednej z nich:
run(). Ta sama metoda jest oczy-
wicie wymagana podczas implementacji interfejsu
Runnable. Cz programistów Javy uwaa, e
klasy pochodne naley tworzy tylko wtedy, gdy stanowi one specjalizacj klasy bazowej. Jeli zatem
nie zamierzasz przesania adnej innej metody klasy
Thread, to najlepiej implementuj interfejs
Runnable. Implementacja interfejsu klasy Runnable umoliwi Twojej klasie wtku równie dziedzicze-
nie po innej klasie ni klasa
Thread.
Jak widzisz, po uruchomieniu wszystkie trzy wtki potomne wspódziel czas procesora. Zwró
uwag, e wtki s uruchamiane w kolejnoci ich utworzenia. Nie jest to regu, Java moe usze-
regowa dziaanie wtków w dowolny sposób. Ze wzgldu na rónice w rodowisku wyko-
nywania informacje wywietlane przez program mog si nieco róni w Twoim przypadku.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
375
Jak ustali, kiedy wtek
zakoczy dziaanie?
Czsto w programie chcielibymy sprawdzi, czy wtek zakoczy swoje dziaanie. Na przy-
kad w poprzednich przykadach w celach demonstracyjnych nie chciaem koczy dziaania
gównego wtku, zanim nie zakoczyy si wtki potomne. W tym celu zawieszaem dziaa-
nie wtku gównego na duej ni wtków potomnych. Jednak w ogólnym przypadku trudno
uzna takie rozwizanie za satysfakcjonujce.
Na szczcie klasa
Thread
dostarcza dwóch sposobów pozwalajcych ustali, czy wtek zako-
czy dziaanie. Pierwszy z nich polega na wywoaniu metody
isAlive()
dla sprawdzanego
wtku. Ogóln posta tej metody przedstawiem poniej:
final boolean isAlive()
Metoda
isAlive()
zwraca warto
true
, jeli wyjtek, dla którego zostaa wywoana, nadal
dziaa. W przeciwnym razie zwraca warto
false
. Aby wypróbowa jej dziaanie, zastp
w poprzednim przykadzie klas
MoreThreads
jej wersj przedstawion na listingu 11.5.
Listing 11.5.
MoreThreads2.java
// Uywa isAlive().
class MoreThreads2 {
public static void main(String args[]) {
System.out.println("Gówny wtek rozpoczyna dziaanie.");
MyThread mt1 = new MyThread("Wtek potomny nr 1");
MyThread mt2 = new MyThread("Wtek potomny nr 2");
MyThread mt3 = new MyThread("Wtek potomny nr 3");
do {
System.out.print(".");
try {
Thread.sleep(100);
}
catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
} while (mt1.thrd.isAlive() ||
mt2.thrd.isAlive() ||
Oczekuje na zakoczenie wszystkich wtków.
mt3.thrd.isAlive());
System.out.println("Wtek gówny koczy dziaanie.");
}
}
Ta wersja programu wywietla podobne informacje jak poprzednia, z t rónic, e metoda
main()
koczy swoje dziaanie, jak tylko zakocz je pozostae wtki. Rónica ta wynika
z zastosowania metody
isAlive()
podczas oczekiwania na zakoczenie wtków potomnych.
Drugi sposób oczekiwania na zakoczenie wtku polega na wywoaniu metody
join()
przed-
stawionej poniej:
Poleć książkę
Kup książkę
376
Java. Przewodnik dla pocztkujcych
final void join( ) throws InterruptedException
Metoda ta czeka, a wtek, dla którego zostaa wywoana, zakoczy dziaanie. Nazwa metody
sugeruje, e wtek, który j wywoa, czeka, a okrelony wtek si z nim poczy (ang. join).
Inne wersje metody
join()
pozwalaj okreli maksymalny czas oczekiwania na zakocze-
nie wtku.
Na listingu 11.6 przedstawiem program, który uywa metody
join()
, aby zagwarantowa,
e gówny wtek zakoczy swoje dziaanie jako ostatni.
Listing 11.6.
JoinThreads.java
// Uywa join().
class MyThread implements Runnable {
Thread thrd;
// Tworzy nowy wtek.
MyThread(String name) {
thrd = new Thread(this, name);
thrd.start(); // uruchamia nowy wtek
}
// Rozpoczyna wykonywanie nowego wtku.
public void run() {
System.out.println(thrd.getName() + " rozpoczyna dziaanie.");
try {
for(int count=0; count < 10; count++) {
Thread.sleep(400);
System.out.println(thrd.getName() +
" jest wykonywany, warto licznika: " + count);
}
}
catch(InterruptedException exc) {
System.out.println(thrd.getName() + " zosta przerwany.");
}
System.out.println(thrd.getName() + " koczy dziaanie.");
}
}
class JoinThreads {
public static void main(String args[]) {
System.out.println("Gówny wtek rozpoczyna dziaanie.");
MyThread mt1 = new MyThread("Wtek potomny nr 1");
MyThread mt2 = new MyThread("Wtek potomny nr 2");
MyThread mt3 = new MyThread("Wtek potomny nr 3");
try {
mt1.thrd.join();
System.out.println("Wtek potomny nr 1 zakoczy dziaanie.");
mt2.thrd.join();
System.out.println("Wtek potomny nr 2 zakoczy dziaanie.");
mt3.thrd.join();
System.out.println("Wtek potomny nr 3 zakoczy dziaanie.");
}
Oczekuj na zakoczenie
konkretnego wtku.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
377
catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
System.out.println("Wtek gówny koczy dziaanie.");
}
}
Poniej przedstawiem wynik dziaania tego programu. Pamitaj, e gdy uruchomisz program
w swoim rodowisku, wynik moe by nieco inny.
Gówny wtek rozpoczyna dziaanie.
Wtek potomny nr 1 rozpoczyna dziaanie.
Wtek potomny nr 3 rozpoczyna dziaanie.
Wtek potomny nr 2 rozpoczyna dziaanie.
Wtek potomny nr 1 jest wykonywany, warto licznika: 0
Wtek potomny nr 2 jest wykonywany, warto licznika: 0
Wtek potomny nr 3 jest wykonywany, warto licznika: 0
Wtek potomny nr 1 jest wykonywany, warto licznika: 1
Wtek potomny nr 2 jest wykonywany, warto licznika: 1
Wtek potomny nr 3 jest wykonywany, warto licznika: 1
Wtek potomny nr 1 jest wykonywany, warto licznika: 2
Wtek potomny nr 2 jest wykonywany, warto licznika: 2
Wtek potomny nr 3 jest wykonywany, warto licznika: 2
Wtek potomny nr 2 jest wykonywany, warto licznika: 3
Wtek potomny nr 1 jest wykonywany, warto licznika: 3
Wtek potomny nr 3 jest wykonywany, warto licznika: 3
Wtek potomny nr 1 jest wykonywany, warto licznika: 4
Wtek potomny nr 2 jest wykonywany, warto licznika: 4
Wtek potomny nr 3 jest wykonywany, warto licznika: 4
Wtek potomny nr 2 jest wykonywany, warto licznika: 5
Wtek potomny nr 1 jest wykonywany, warto licznika: 5
Wtek potomny nr 3 jest wykonywany, warto licznika: 5
Wtek potomny nr 1 jest wykonywany, warto licznika: 6
Wtek potomny nr 2 jest wykonywany, warto licznika: 6
Wtek potomny nr 3 jest wykonywany, warto licznika: 6
Wtek potomny nr 1 jest wykonywany, warto licznika: 7
Wtek potomny nr 2 jest wykonywany, warto licznika: 7
Wtek potomny nr 3 jest wykonywany, warto licznika: 7
Wtek potomny nr 2 jest wykonywany, warto licznika: 8
Wtek potomny nr 1 jest wykonywany, warto licznika: 8
Wtek potomny nr 3 jest wykonywany, warto licznika: 8
Wtek potomny nr 2 jest wykonywany, warto licznika: 9
Wtek potomny nr 1 jest wykonywany, warto licznika: 9
Wtek potomny nr 2 koczy dziaanie.
Wtek potomny nr 1 koczy dziaanie.
Wtek potomny nr 1 zakoczy dziaanie.
Wtek potomny nr 2 zakoczy dziaanie.
Wtek potomny nr 3 jest wykonywany, warto licznika: 9
Wtek potomny nr 3 koczy dziaanie.
Wtek potomny nr 3 zakoczy dziaanie.
Wtek gówny koczy dziaanie.
Jak atwo zauway, powrót sterowania z metody
join()
oznacza zakoczenie wtku.
Poleć książkę
Kup książkę
378
Java. Przewodnik dla pocztkujcych
Priorytety wtków
Z kadym wtkiem zwizany jest priorytet. Priorytet wtku decyduje, przynajmniej czciowo,
o tym, ile czasu procesora otrzyma dany wtek w porównaniu do innych wtków. W ogólnym
przypadku spodziewamy si, e wtek o niskim priorytecie otrzyma mao czasu procesora,
a wtek o wysokim priorytecie znacznie wicej. Ilo czasu procesora przydzielonego wtkowi
ma istotny wpyw na charakterystyk wykonania wtku i jego interakcj z innymi wtkami
wykonywanymi równolegle w systemie.
Na ilo czasu procesora przydzielan wtkowi maj wpyw oprócz priorytetu wtku take
inne czynniki. Na przykad: jeli wtek o wysokim priorytecie oczekuje na pewien zasób, na
przykad na wprowadzenie danych z klawiatury, to w tym czasie wykonywane bd wtki o ni-
szym priorytecie. Jednak gdy wtek o wysokim priorytecie uzyska dostp do zasobu, to wtki
o niszym priorytecie zostan wywaszczone z procesora i wznowione zostanie wykonywa-
nie wtku o wysokim priorytecie. Innym czynnikiem wpywajcym na szeregowanie wtków
jest sposób implementacji wielozadaniowoci w danym systemie (patrz ramka „Ekspert odpo-
wiada” na kocu tego podrozdziau). Dlatego te nawet jeli nadasz róne priorytety wtkom
programu, nie musi to oznacza, e jeden z wtków bdzie wykonywany szybciej lub czciej
ni inny wtek. Wtek o wysokim priorytecie ma jedynie potencjalnie lepszy dostp do pro-
cesora.
Wtek potomny ma po uruchomieniu taki sam priorytet jak wtek gówny. Priorytet wtku
moesz zmieni za pomoc metody
setPriority()
zdefiniowanej w klasie
Thread
. Poniej
przedstawiem jej ogóln posta.
final void setPriority(int priorytet)
W tym przypadku parametr
priorytet
okrela now warto priorytetu dla wtku, dla którego
wywoano metod. Warto parametru
priorytet
musi nalee do przedziau od
MIN_PRIORITY
do
MAX_PRIORITY
. Obecnie stae te maj wartoci odpowiednio 1 i 10. Aby przywróci wt-
kowi zwyky priorytet, podajesz warto
NORM_PRIORITY
, obecnie równ 5. Wymienione wartoci
priorytetów zostay zadeklarowane jako
static final
w klasie
Thread
.
Biecy priorytet wtku moesz uzyska, wywoujc metod
getPriority()
zdefiniowan
w klasie
Thread
, któr przedstawiam poniej:
final int getPriority( )
Przykad programu zamieszczony na listingu 11.7 demonstruje uycie dwóch wtków o rónych
priorytetach. Wtki te tworzone s jako instancje klasy
Priority
. Metoda
run()
tej klasy zawiera
ptl zliczajc iteracje. Ptla koczy dziaanie, gdy wykona 10 000 000 iteracji lub gdy
zmienna
stop
zadeklarowana jako
static
ma warto
true
. Pocztkowo zmienna ta ma
warto
false
, a warto
true
nadaje jej ten wtek, który pierwszy zakoczy swoje dziaanie.
W ten sposób drugi z wtków równie koczy swoje dziaanie, gdy tylko otrzyma czas proce-
sora. W kadym przebiegu ptli acuch
currentName
jest porównywany z nazw wykony-
wanego wtku. Jeli s róne, oznacza to, e nastpio przeczenie wtków. Wtedy wywie-
tlona zostaje nazwa nowego wtku, która zostaje równie przypisana zmiennej
currentName
.
Wywietlanie informacji na skutek przeczenia wtku umoliwia uytkownikowi obserwacj
dostpu obu wtków do procesora. Po zakoczeniu dziaania obu wtków program wywietla
liczb iteracji obu ptli.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
379
Listing 11.7.
PriorityDemo.java
// Demonstruje priorytety wtków.
class Priority implements Runnable {
int count;
Thread thrd;
static boolean stop = false;
static String currentName;
/* Tworzy nowy wtek. Zwró uwag, e ten
konstruktor nie uruchamia wtków. */
Priority(String name) {
thrd = new Thread(this, name);
count = 0;
currentName = name;
}
// Rozpoczyna wykonywanie nowego wtku.
public void run() {
System.out.println(thrd.getName() + " rozpoczyna dziaanie.");
do {
count++;
if(currentName.compareTo(thrd.getName()) != 0) {
currentName = thrd.getName();
System.out.println(currentName + " jest wykonywany.");
}
} while(stop == false && count < 10000000);
stop = true;
System.out.println("\n" + thrd.getName() +
" koczy dziaanie.");
}
}
class PriorityDemo {
public static void main(String args[]) {
Priority mt1 = new Priority("Wtek o wysokim priorytecie");
Priority mt2 = new Priority("Wtek o niskim priorytecie");
// okrela priorytet wtków
mt1.thrd.setPriority(Thread.NORM_PRIORITY+2);
Wtek
mt1 otrzymuje
mt2.thrd.setPriority(Thread.NORM_PRIORITY-2);
wyszy priorytet ni wtek
mt2.
// uruchamia wtki
mt1.thrd.start();
mt2.thrd.start();
try {
mt1.thrd.join();
mt2.thrd.join();
}
catch(InterruptedException exc) {
System.out.println("Gówny wtek rozpoczyna dziaanie.");
}
Wtek, który pierwszy
osignie 10 000 000,
zatrzymuje wszystkie wtki.
Poleć książkę
Kup książkę
380
Java. Przewodnik dla pocztkujcych
System.out.println("\nWtek o wysokim priorytecie odliczy do " +
mt1.count);
System.out.println("Wtek o niskim priorytecie odliczy do " +
mt2.count);
}
}
A oto przykad dziaania programu:
Wtek o wysokim priorytecie rozpoczyna dziaanie.
Wtek o wysokim priorytecie jest wykonywany.
Wtek o niskim priorytecie rozpoczyna dziaanie.
Wtek o niskim priorytecie jest wykonywany.
Wtek o wysokim priorytecie jest wykonywany.
Wtek o niskim priorytecie koczy dziaanie.
Wtek o wysokim priorytecie koczy dziaanie.
Wtek o wysokim priorytecie odliczy do 10000000
Wtek o niskim priorytecie odliczy do 8183
W tym przypadku wtek o wysokim priorytecie zawaszczy wikszo czasu procesora.
Oczywicie dokadny wynik dziaania programu zaley od liczby procesorów w systemie, ich
szybkoci, systemu operacyjnego i liczby innych zada wykonywanych równoczenie przez
system.
Ekspert odpowiada
Pytanie: Czy sposób implementacji wielozadaniowoci w konkretnym systemie operacyjnym ma
wpyw na to, ile czasu procesora otrzymuje wtek?
Odpowied: Oprócz priorytetu wtku najwikszy wpyw na wykonanie wtku ma wanie sposób imple-
mentacji wielozadaniowoci i szeregowania zada w systemie operacyjnym. Niektóre systemy sto-
suj wielozadaniowo z wywaszczaniem, co gwarantuje, e kady wtek otrzymuje czas procesora,
przynajmniej okazjonalnie. W systemach, które nie uywaj wywaszczania, wykonywany wtek musi
sam zwolni procesor, zanim bdzie moliwe wykonywanie innego wtku. W takich systemach atwo
o sytuacj, w której jeden wtek zawaszczy procesor, uniemoliwiajc wykonywanie innych wtków.
Synchronizacja
Gdy uywasz w programie wielu wtków, moe pojawi si konieczno skoordynowania
dziaania niektórych z nich. Proces, który to umoliwia, nazywamy synchronizacj. Najczst-
szym powodem synchronizacji jest sytuacja, gdy dwa lub wicej wtków wymaga dostpu
do wspódzielonego zasobu, który moe by uywany w danej chwili tylko przez jeden wtek.
Na przykad gdy jeden wtek zapisuje dane w pliku, inny wtek nie moe wykonywa zapisu
w tym samym pliku w tym samym czasie. Innym powodem stosowania synchronizacji jest
oczekiwanie wtku na zdarzenie, którego przyczyn jest inny wtek. W tym przypadku musi
istnie sposób zawieszenia wykonywania wtku do momentu, w którym nastpi wspomniane
zdarzenie. Wtedy wtek musi wznowi wykonywanie.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
381
Kluczem do synchronizacji wtków w Javie jest koncepcja monitora. Monitor kontroluje
dostp do obiektu, uywajc blokad. Gdy dostp do obiektu zostanie zablokowany przez jeden
wtek, obiekt nie jest dostpny dla innych wtków. Dopiero gdy wtek przestanie uywa
obiektu, blokada zostaje zwolniona i obiekt jest dostpny dla innych wtków.
Z kadym obiektem Javy zwizany jest monitor. Monitory zostay wbudowane w jzyk Java
i dziki temu Java umoliwia synchronizacj dostpu do wszystkich obiektów. Odbywa si
ona przez zastosowanie sowa kluczowego
synchronized
i kilku metod, którymi dysponuj
wszystkie obiekty. Poniewa Jav od pocztku projektowano z myl o synchronizacji, posu-
giwanie si tym mechanizmem jest duo atwiejsze, ni mogoby si wydawa. W wielu pro-
gramach synchronizacja dostpu do obiektów odbywa si prawie w transparentny sposób.
Istniej dwa sposoby zastosowania synchronizacji w Twoim kodzie. Oba wymagaj uycia
sowa kluczowego
synchronized
i oba zostan omówione w tym rozdziale.
Synchronizacja metod
Synchronizacj dostpu do metody moesz zapewni, uywajc w jej deklaracji sowa klu-
czowego
synchronized
. Wywoanie takiej metody powoduje, e monitor blokuje dostp do
obiektu. Gdy obiekt jest zablokowany, aden inny wtek nie moe wywoa tej metody ani
adnej innej metody tego obiektu zadeklarowanej w jego klasie jako
synchronized
. Gdy dzia-
anie metody koczy si, monitor odblokowuje obiekt, umoliwiajc tym samym jego uycie
przez kolejny wtek. W ten sposób synchronizacja dostpu do obiektu odbywa si praktycznie
bez jakiegokolwiek dodatkowego wysiku ze strony programisty.
Program przedstawiony na listingu 11.8 demonstruje dziaanie mechanizmu synchronizacji na
przykadzie metody
sumArray()
sumujcej elementy tablicy zawierajcej liczby cakowite.
Listing 11.8.
Sync.java
// Synchronizacja dostpu do metody.
class SumArray {
private int sum;
synchronized int sumArray(int nums[]) {
Dostp do metody
sumArray()
sum = 0; // zeruje sum
jest synchronizowany.
for(int i=0; i<nums.length; i++) {
sum += nums[i];
System.out.println(Thread.currentThread().getName() +
" wyliczy sum czciow równ " + sum);
try {
Thread.sleep(10); // umoliwia przeczenie wtków
}
catch(InterruptedException exc) {
System.out.println("Wtek zosta przerwany.");
}
}
return sum;
Poleć książkę
Kup książkę
382
Java. Przewodnik dla pocztkujcych
}
}
class MyThread implements Runnable {
Thread thrd;
static SumArray sa = new SumArray();
int a[];
int answer;
// Tworzy nowy wtek.
MyThread(String name, int nums[]) {
thrd = new Thread(this, name);
a = nums;
thrd.start(); // uruchamia wtek
}
// Rozpoczyna wykonywanie nowego wtku.
public void run() {
int sum;
System.out.println(thrd.getName() + " rozpoczyna dziaanie.");
answer = sa.sumArray(a);
System.out.println(thrd.getName() +
" wyliczy sum równ " + answer);
System.out.println(thrd.getName() + " koczy dziaanie.");
}
}
class Sync {
public static void main(String args[]) {
int a[] = {1, 2, 3, 4, 5};
MyThread mt1 = new MyThread("Wtek potomny nr 1", a);
MyThread mt2 = new MyThread("Wtek potomny nr 2", a);
try {
mt1.thrd.join();
mt2.thrd.join();
}
catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
}
}
A oto przykad dziaania tego programu (kolejno komunikatów moe by w Twoim przy-
padku nieco inna).
Wtek potomny nr 1 rozpoczyna dziaanie.
Wtek potomny nr 2 rozpoczyna dziaanie.
Wtek potomny nr 1 wyliczy sum czciow równ 1
Wtek potomny nr 1 wyliczy sum czciow równ 3
Wtek potomny nr 1 wyliczy sum czciow równ 6
Wtek potomny nr 1 wyliczy sum czciow równ 10
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
383
Wtek potomny nr 1 wyliczy sum czciow równ 15
Wtek potomny nr 2 wyliczy sum czciow równ 1
Wtek potomny nr 1 wyliczy sum równ 15
Wtek potomny nr 1 koczy dziaanie.
Wtek potomny nr 2 wyliczy sum czciow równ 3
Wtek potomny nr 2 wyliczy sum czciow równ 6
Wtek potomny nr 2 wyliczy sum czciow równ 10
Wtek potomny nr 2 wyliczy sum czciow równ 15
Wtek potomny nr 2 wyliczy sum równ 15
Wtek potomny nr 2 koczy dziaanie.
Przeanalizujmy szczegóowo dziaanie tego programu. Tworzy on trzy klasy. Pierwsz z nich
jest
SumArray
. Zawiera ona metod
sumArray()
, która oblicza sum elementów tablicy przecho-
wujcej wartoci cakowite. Druga klasa,
MyThread
, uywa obiektu typu
SumArray
. Referencj
sa
tego obiektu zadeklarowaem jako
static
i wobec tego istnieje tylko jedna jej kopia
wspódzielona przez wszystkie obiekty klasy
MyThread
. Ostatnia z klas,
Sync
, tworzy dwa
wtki obliczajce sum zawartoci tej samej tablicy.
Metoda
sumArray()
wywouje metod
sleep()
, aby umoliwi przeczenie wtków. Jednak
przeczenie nie jest moliwe, gdy metoda
sumArray()
zostaa zadeklarowana jako
synchronized
i wobec tego nie moe by uywana równoczenie przez dwa lub wicej wtków. Zatem gdy
drugi z wtków potomnych rozpoczyna dziaanie, nie moe wywoa metody
sumArray()
,
dopóki nie wykona jej pierwszy wtek. Synchronizacja dostpu do metody gwarantuje w tym
wypadku poprawny wynik jej dziaania.
Aby w peni zrozumie efekt sowa kluczowego
synchronized
, spróbuj usun je z deklaracji
metody
sumArray()
. Dostp do tej metody przestanie podlega synchronizacji i wiele wtków
bdzie mogo jej uywa równoczenie. Problem polega na tym, e suma czciowa jest prze-
chowywana w skadowej
sum
, która jest modyfikowana przez kady wtek wywoujcy metod
sumArray()
dla obiektu
sa
zadeklarowanego jako
static
. Jeli zatem dwa wtki wywoaj
równoczenie metod
sa.sumArray()
, wyniki jej dziaania bd niepoprawne, poniewa ska-
dowa
sum
bdzie przechowywa na przemian sumy czciowe obliczane przez kady z wt-
ków. Poniej przedstawiem przykad dziaania programu po usuniciu sowa kluczowego
synchronized
z deklaracji metody
sumArray()
(wynik dziaania w Twoim przypadku moe
si róni).
Wtek potomny nr 1 rozpoczyna dziaanie.
Wtek potomny nr 2 rozpoczyna dziaanie.
Wtek potomny nr 1 wyliczy sum czciow równ 1
Wtek potomny nr 2 wyliczy sum czciow równ 1
Wtek potomny nr 1 wyliczy sum czciow równ 3
Wtek potomny nr 1 wyliczy sum czciow równ 8
Wtek potomny nr 2 wyliczy sum czciow równ 8
Wtek potomny nr 2 wyliczy sum czciow równ 11
Wtek potomny nr 1 wyliczy sum czciow równ 15
Wtek potomny nr 1 wyliczy sum czciow równ 20
Wtek potomny nr 2 wyliczy sum czciow równ 24
Wtek potomny nr 2 wyliczy sum czciow równ 29
Wtek potomny nr 1 wyliczy sum równ 24
Wtek potomny nr 1 koczy dziaanie.
Wtek potomny nr 2 wyliczy sum równ 29
Wtek potomny nr 2 koczy dziaanie.
Poleć książkę
Kup książkę
384
Java. Przewodnik dla pocztkujcych
Powysze informacje pokazuj, e oba wtki potomne wywouj równoczenie metod
sa.sumArray()
, przypisujc skadowej
sum
niewaciwe wartoci. Zanim przejdziemy do nastp-
nego zagadnienia, podsumujmy najwaniejsze fakty zwizane z synchronizacj metod:
synchronizacja metody polega na umieszczeniu sowa kluczowego
synchronized
w deklaracji metody;
synchronizacja dostpu do metody powoduje, e jej wywoanie dla dowolnego obiektu
powoduje jego zablokowanie i aden inny wtek nie moe wywoa dla tego samego
obiektu adnej metody zadeklarowanej jako
synchronized
;
inne wtki próbujce wywoa metod zadeklarowan jako
synchronized
dla obiektu,
do którego dostp zosta zablokowany przez monitor, przechodz w stan oczekiwania
do momentu, w którym obiekt zostanie odblokowany;
gdy wtek koczy wykonywanie metody
synchronized
, dostp 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
przykad moe wystpi konieczno zapewnienia synchronizacji dostpu do metody, która
nie zostaa zadeklarowana jako
synchronized
. Moe si to zdarzy, gdy uywasz cudzych
klas i nie masz dostpu do ich kodu ródowego. Nie moesz zatem doda sowa kluczowego
synchronized
w deklaracji interesujcej Ci metody. W jaki sposób moesz zatem zapewni
synchronizacj dostpu do obiektu tej klasy? Rozwizanie tego problemu jest na szczcie
bardzo proste: wystarczy umieszcza wywoania metod tej klasy w bloku oznaczonym jako
synchronized
.
Poniej przedstawiem ogóln posta bloku
synchronized
:
synchronized(refobj) {
// instrukcje wymagajce synchronizacji
}
W tym przypadku
refobj
jest referencj obiektu, do którego dostp wymaga synchronizacji.
Gdy wtek rozpocznie wykonywanie bloku
synchronized
, aden inny wtek nie moe wywoa
metody dla obiektu
refobj
, dopóki biecy wtek nie opuci tego bloku.
Kolejny sposób synchronizacji wywoa metody
sumArray()
polega zatem na ich umieszczeniu
w bloku
synchronized
. Ilustruje to wersja programu przedstawiona na listingu 11.9.
Listing 11.9.
Sync2.java
// Uywa bloku synchronized
// dla synchronizacji dostpu
// do metody sumArray.
class SumArray {
private int sum;
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
385
int sumArray(int nums[]) {
W tym wypadku dostp do metody
sumArray()
sum = 0; // zeruje sum
nie podlega synchronizacji.
for(int i=0; i<nums.length; i++) {
sum += nums[i];
System.out.println(Thread.currentThread().getName() +
" wyliczy sum czciow równ " + sum);
try {
Thread.sleep(10); // umoliwia przeczenie wtków
}
catch(InterruptedException exc) {
System.out.println("Wtek zosta przerwany.");
}
}
return sum;
}
}
class MyThread implements Runnable {
Thread thrd;
static SumArray sa = new SumArray();
int a[];
int answer;
// Tworzy nowy wtek.
MyThread(String name, int nums[]) {
thrd = new Thread(this, name);
a = nums;
thrd.start(); // uruchamia wtek
}
// Rozpoczyna wykonywanie nowego wtku.
public void run() {
int sum;
System.out.println(thrd.getName() + " rozpoczyna dziaanie.");
// synchronizuje wywoania metody sumArray()
synchronized(sa) {
Synchronizacja wywoa metody
sumArray() dla obiektu sa.
answer = sa.sumArray(a);
}
System.out.println(thrd.getName() +
" wyliczy sum równ " + answer);
System.out.println(thrd.getName() + " koczy dziaanie.");
}
}
class Sync2 {
public static void main(String args[]) {
int a[] = {1, 2, 3, 4, 5};
MyThread mt1 = new MyThread("Wtek potomny nr 1", a);
MyThread mt2 = new MyThread("Wtek potomny nr 2", a);
try {
mt1.thrd.join();
Poleć książkę
Kup książkę
386
Java. Przewodnik dla pocztkujcych
mt2.thrd.join();
} catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
}
}
Wynik dziaania tej wersji programu bdzie poprawny, taki sam jak w przypadku wykorzy-
stania metody zadeklarowanej jako
synchronized
.
Ekspert odpowiada
Pytanie: Syszaem co o „API wspóbienoci”. Do czego one su? Do czego suy szkielet
Fork/Join?
Odpowied: API wspóbienoci udostpniono w pakiecie
java.util.concurrent (i jego pakietach
podrzdnych) w celu umoliwienia w Javie programowania wspóbienego. Klasy te implementuj
midzy innymi synchronizatory, pule wtków, menedery wykonania i blokady umoliwiajce sterowa-
nie wykonaniem wtków. Jedn z najciekawszych moliwoci oferowanych przez API wspóbienoci
jest szkielet Fork/Join wprowadzony w JDK 7.
Szkielet ten umoliwia tak zwane programowanie równolege. Nazwy tej uywa si do okrelenia
technik pozwalajcych wykorzysta zalety komputerów o dwu lub wicej procesorach (wczajc w to
systemy wielordzeniowe) poprzez podzia zadania na podzadania i wykonywanie kadego podzada-
nia na osobnym procesorze. Rozwizanie takie pozwala zwikszy szybko wykonywania dziaania
i poprawi efektywno systemu. Podstawow zalet szkieletu Fork/Join jest atwo uycia. Upraszcza
on tworzenie kodu wielowtkowego, który automatycznie skaluje si tak, aby wykorzysta liczb
procesorów dostpnych w systemie. Tym samym sprowadza tworzenie rozwiza wspóbienych do
poziomu nie trudniejszego ni typowe zadania programowania, takie jak na przykad operacje na
elementach tablicy. API wspóbienoci, a w szczególnoci szkielet Fork/Join, warte s poznania, gdy
nabierzesz wikszego dowiadczenia w tworzeniu programów wielowtkowych.
Komunikacja midzywtkowa
Rozwamy nastpujc sytuacj. Wtek T wykonuje wanie metod zadeklarowan jako
synchronized
i wymaga dostpu do zasobu R, który jest tymczasowo niedostpny. Co powi-
nien zrobi wtek T? Jeli zacznie sprawdza w ptli dostpno zasobu R, to zablokuje
uywany obiekt, uniemoliwiajc dostp innym wtkom. Rozwizanie takie jest dalekie od
optymalnego, poniewa czciowo redukuje zalety programowania wielowtkowego. Lepiej
bdzie, jeli wtek T zwolni tymczasowo wykorzystywany obiekt, umoliwiajc wykonywanie
innych wtków. Gdy zasób R stanie si dostpny, wtek T zostanie powiadomiony i wznowi
dziaanie. Takie rozwizanie wymaga jednak komunikacji midzywtkowej, dziki której jeden
wtek moe powiadomi inne, e zosta zablokowany, a sam zosta powiadomiony, e moe
wznowi dziaanie. Java umoliwia komunikacj midzywtkow za pomoc metod
wait()
,
notify()
i
notifyAll()
.
Metody
wait()
,
notify()
i
notifyAll()
s dostpne dla kadego obiektu, poniewa zostay
zaimplementowane w klasie
Object
. Metody te mog by wywoywane tylko w kontekcie
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
387
dziaania mechanizmu synchronizacji. Uywamy ich w nastpujcy sposób. Gdy wtek zostaje
czasowo zablokowany, wywouje metod
wait()
. Wykonanie wtku zostaje zawieszone,
a monitor obiektu zwalnia blokad, umoliwiajc innemu wtkowi dostp do obiektu. Zawie-
szony wtek wznowi póniej swoje dziaanie, gdy inny wtek wywoa dla tego samego obiektu
metod
notify()
lub
notifyAll()
.
Poniej przedstawiem róne wersje metody
wait()
zdefiniowane w klasie
Object
:
final void wait( ) throws InterruptedException
final void wait(long milisekund) throws InterruptedException
final void wait(long milisekund, int nanosekund) throws InterruptedException
Pierwsza wersja zawiesza wykonywanie wtku do momentu wywoania metody
notify()
lub
notifyAll()
. Druga podobnie, ale wtek nie bdzie oczekiwa duej ni podan liczb
milisekund
. Trzecia wersja umoliwia jeszcze dokadniejsze okrelenie maksymalnego czasu
oczekiwania z dokadnoci do pojedynczych
nanosekund
.
Poniej przedstawiem ogóln posta metod
notify()
i
notifyAll()
:
final void notify( )
final void notifyAll( )
Wywoanie metody
notify()
powoduje wznowienie wykonywania oczekujcego wtku.
Wywoanie metody
notifyAll()
powiadamia wszystkie wtki, a dostp do obiektu uzyskuje
wtek o najwyszym priorytecie.
Zanim przyjrzymy si przykadowi zastosowania tych metod, musz uczyni jeszcze jedn
wan uwag. Chocia w normalnych warunkach metoda
wait()
powoduje oczekiwanie
wtku na wywoanie metody
notify()
lub
notifyAll()
, istnieje bardzo rzadko spotykana
moliwo, e wtek zakoczy oczekiwanie na skutek tak zwanego faszywego przebudzenia.
Omówienie skomplikowanych warunków, które prowadz do takiej sytuacji, wykracza poza
zakres tej ksiki. Ze wzgldu na moliwo wystpienia faszywego przebudzenia wtku
firma Oracle zaleca wywoywanie metody
wait()
w ptli sprawdzajcej warunek, na którego
spenienie oczekuje wtek. W nastpnym przykadzie zastosujemy t technik.
Przykad uycia metod wait() i notify()
Aby atwiej Ci byo zrozumie zastosowania metod
wait()
i
notify()
, stworzymy teraz program
symulujcy tykanie zegara przez wywietlanie na przemian sów „tik” i „tak”. W tym celu
stworzymy klas
TickTock
zawierajc dwie metody:
tick()
i
tock()
. Metoda
tick()
wywie-
tli sowo
"tik"
, a metoda
tock()
sowo
"tak"
. Aby uruchomi symulacj zegara, utworzymy
dwa wtki, z których jeden bdzie wywoywa metod
tick()
, a drugi metod
tock()
. Wtki
te musz by wykonywane w taki sposób, aby program wywietla na przemian sowa „tik”
i „tak”. Kod ródowy programu przedstawiem na listingu 11.10.
Listing 11.10.
ThreadCom.java
// Uywa metod wait() i notify()
// do stworzenia symulacji zegara.
class TickTock {
Poleć książkę
Kup książkę
388
Java. Przewodnik dla pocztkujcych
String state; // przechowuje stan zegara
synchronized void tick(boolean running) {
if(!running) { // zatrzymuje zegar
state = "ticked";
notify(); // powiadamia oczekujcy wtek
return;
}
System.out.print("tik ");
state = "ticked"; // zmienia stan zegara na "ticked"
notify(); // umoliwia wykonanie metody tock()
Metoda
tick() powiadamia metod tock().
try {
while(!state.equals("tocked"))
wait(); // oczekuje na zakoczenie metody tock()
Metoda tick() czeka na zakoczenie
}
metody tock().
catch(InterruptedException exc) {
System.out.println("Wtek zosta przerwany.");
}
}
synchronized void tock(boolean running) {
if(!running) { // zatrzymuje zegar
state = "tocked";
notify(); // powiadamia oczekujcy wtek
return;
}
System.out.println("tak");
state = "tocked"; // zmienia stan zegara na "tocked"
notify(); // umoliwia wykonanie metody tick()
Metoda tock() powiadamia metod tick().
try {
while(!state.equals("ticked"))
wait(); // oczekuje na zakoczenie metody tick()
Metoda tock() czeka
}
na zakoczenie metody tick().
catch(InterruptedException exc) {
System.out.println("Wtek zosta przerwany.");
}
}
}
class MyThread implements Runnable {
Thread thrd;
TickTock ttOb;
// Tworzy nowy wtek.
MyThread(String name, TickTock tt) {
thrd = new Thread(this, name);
ttOb = tt;
thrd.start(); // uruchamia wtek
}
// Rozpoczyna wykonywanie nowego wtku.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
389
public void run() {
if(thrd.getName().compareTo("tik") == 0) {
for(int i=0; i<5; i++) ttOb.tick(true);
ttOb.tick(false);
}
else {
for(int i=0; i<5; i++) ttOb.tock(true);
ttOb.tock(false);
}
}
}
class ThreadCom {
public static void main(String args[]) {
TickTock tt = new TickTock();
MyThread mt1 = new MyThread("tik", tt);
MyThread mt2 = new MyThread("tak", tt);
try {
mt1.thrd.join();
mt2.thrd.join();
} catch(InterruptedException exc) {
System.out.println("Wtek gówny zosta przerwany.");
}
}
}
A oto wynik dziaania tego programu:
tik tak
tik tak
tik tak
tik tak
tik tak
Przyjrzyjmy si bliej dziaaniu tego programu. Sercem symulacji zegara jest klasa
TickTock
.
Zawiera ona dwie metody,
tick()
i
tock()
, które komunikuj si ze sob, aby zagwarantowa,
e po metodzie
tick()
zostanie zawsze wykonana metoda
tock()
, a po niej znowu metoda
tick()
i tak dalej. Zwró uwag na skadow
state
. Gdy dziaa symulacja zegara, skadowa
state
przechowuje acuch
"ticked"
lub
"tocked"
informujcy o biecym stanie zegara.
Metoda
main()
tworzy obiekt
tt
klasy
TickTock
i uywa go do uruchomienia dwóch wtków
potomnych.
Wtki te opieraj si na obiektach typu
MyThread
. Konstruktor klasy
MyThread
ma dwa para-
metry. Pierwszym jest nazwa wtku,
"tik"
lub
"tak"
. Drugim jest referencja obiektu typu
TickTock
,
tt
w tym przypadku. Wewntrz metody
run()
klasy
MyThread
wywoana zostaje
metoda
tick()
, jeli nazw wtku jest
"tik"
. Jeli nazw jest
"tak"
, wywoana zostaje metoda
tock()
. Kada z tych metod zostaje wywoana pi razy z argumentem
true
. Ostatnie wywoa-
nie przekazuje kadej metodzie argument
false
, co powoduje zatrzymanie symulacji zegara.
Najwaniejsz cz symulacji zegara stanowi metody
tick()
i
tock()
klasy
TickTock
. Przyj-
rzyjmy si metodzie
tick()
, której kod przedstawiem poniej.
Poleć książkę
Kup książkę
390
Java. Przewodnik dla pocztkujcych
synchronized void tick(boolean running) {
if(!running) { // zatrzymuje zegar
state = "ticked";
notify(); // powiadamia oczekujcy wtek
return;
}
System.out.print("tik ");
state = "ticked"; // zmienia stan zegara na "ticked"
notify(); // umoliwia wykonanie metody tock()
try {
while(!state.equals("tocked"))
wait(); // oczekuje na zakoczenie metody tock()
}
catch(InterruptedException exc) {
System.out.println("Wtek zosta przerwany.");
}
}
Zwró uwag, e metoda
tick()
zostaa zadeklarowana jako
synchronized
. Jak ju wspo-
mniaem, metody
wait()
i
notify()
znajduj zastosowanie tylko w przypadku synchronizacji
dostpu do metod. Metoda rozpoczyna dziaanie od sprawdzenia wartoci parametru
running
.
Parametr ten jest uywany do zakoczenia dziaania symulacji zegara. Jeli ma warto
false
,
zegar zostaje zatrzymany. W takim przypadku skadowa
state
otrzymuje warto
"ticked"
i wywoana zostaje metoda
notify()
, aby umoliwi dziaanie oczekujcego wtku. Za chwil
wrócimy jeszcze do tego punktu.
Jeli zegar dziaa, metoda wywietla sowo
"tik"
, nadaje skadowej
state
warto
"ticked"
i wywouje metod
notify()
. Wywoanie metody
notify()
umoliwia wznowienie dziaania
wtku, który oczekiwa na dostp do tego samego obiektu. Nastpnie w ptli
while
wywoy-
wana jest metoda
wait()
. Wywoanie metody
wait()
powoduje zawieszenie wykonywania
metody
tick()
do momentu, w którym inny wtek wywoa metod
notify()
. Zatem wyko-
nanie ptli zostanie równie wstrzymane do momentu, w którym inny wtek wywoa metod
notify()
dla tego samego obiektu. W rezultacie wywoanie metody
tick()
powoduje wywie-
tlenie jednego sowa
"tik"
, wznowienie innego wtku i zawieszenie wasnego wykonania.
Ptla
while
, która wywouje metod
wait()
, sprawdza, czy skadowa
state
ma warto
"tocked"
,
co zdarzy si dopiero po wywoaniu metody
tock()
. Jak ju wczeniej wyjaniem, zastosowa-
nie ptli
while
do sprawdzania tego warunku ma zapobiec faszywemu przebudzeniu wtku.
Gdy metoda
wait()
zwróci sterowanie, a skadowa
state
nie ma wartoci
"tocked"
, oznacza to
wanie wystpienie faszywego przebudzenia i metoda
wait()
zostaje wywoana ponownie.
Metoda
tock()
stanowi dokadn kopi metody
tick()
, z t rónic, e wywietla sowo
"tak"
i nadaje skadowej
state
warto
"tocked"
. Zatem metoda
tock()
najpierw wywietla sowo
"tak"
, wywouje metod
notify()
i nastpnie zawiesza swoje dziaanie. Metody
tick()
i
tack()
mog dziaa tylko razem, przy czym po wywoaniu metody
tick()
musi nastpi wywoanie
metody
tock()
, po którym znowu nastpuje wywoanie metody
tick()
i tak dalej. Dziaanie
tych metod jest wzajemnie zsynchronizowane.
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
391
Po zatrzymaniu zegara metoda
notify()
zostaje wywoana ostatni raz, aby wznowi dziaanie
drugiego wtku. Pamitaj, e metody
tick()
i
tock()
wywouj zawsze metod
wait()
po
wywietleniu komunikatu. Zatem gdy zegar zostanie zatrzymany, jeden z wtków bdzie si
znajdowa w stanie oczekiwania. Jego dziaanie mona wznowi wanie za pomoc ostatniego
wywoania metody
notify()
. Spróbuj usun to wywoanie metody
notify()
i zaobserwo-
wa efekt. Zobaczysz, e program „zawiesi si” i bdziesz musia przerwa jego dziaanie,
naciskajc Ctrl+C. Dzieje si tak, poniewa gdy ostatnie wywoanie metody
tock()
spowoduje
wywoanie metody
wait()
, to nie bdzie odpowiadajcego mu wywoania metody
notify()
,
które pozwolioby metodzie
tock()
zakoczy dziaanie. Zatem metoda
tock()
oczekuje
wtedy w nieskoczono.
Jeli masz jeszcze wtpliwoci, czy rzeczywicie wywoania metod
wait()
i
notify()
s
konieczne dla prawidowego dziaania symulacji zegara, zastp klas
TockTock
jej ponisz
wersj, z której usunem wywoania metod
wait()
i
notify()
.
// Bez wywoa metod wait() i notify().
class TickTock {
String state; // przechowuje stan zegara
synchronized void tick(boolean running) {
if(!running) { // zatrzymuje zegar
state = "ticked";
return;
}
System.out.print("tik ");
state = "ticked"; // zmienia stan zegara na "ticked"
}
synchronized void tock(boolean running) {
if(!running) { // zatrzymuje zegar
state = "tocked";
return;
}
System.out.println("tak");
state = "tocked"; // zmienia stan zegara na "tocked"
}
}
Po zastpieniu klasy
TickTock
now wersj program wywietli ponisze komunikaty:
tik tik tik tik tik tak
tak
tak
tak
tak
Metody
tick()
i
tock()
nie wspópracuj ju ze sob!
Poleć książkę
Kup książkę
392
Java. Przewodnik dla pocztkujcych
Ekspert odpowiada
Pytanie: Spotkaem si z terminem zakleszczenie w odniesieniu do nieprawidowo dziaajcych
programów wielowtkowych. Na czym polega ta sytuacja i jak jej unika? Na czym polega sytu-
acja wycigu i jak mog jej unikn?
Odpowied: Zakleszczenie, jak wskazuje nazwa, jest sytuacj, w której jeden wtek czeka, a drugi
wtek wykona pewn operacj, ale drugi wtek czeka wanie na pierwszy. Dziaanie obu wtków jest
wstrzymane, wtki oczekuj na siebie wzajemnie. Przypomina to troch dwie nadzwyczaj uprzejme
osoby, które nie mog przekroczy progu, poniewa kada chce ustpi drugiej.
Unikanie zakleszcze wydaje si proste, ale takie nie jest. Sama analiza kodu programu czsto nie
wystarcza do ustalenia przyczyny zakleszczenia, poniewa w czasie wykonania programu midzy
wtkami mog zachodzi skomplikowane zalenoci czasowe. Unikanie zakleszcze wymaga dba-
oci w programowaniu oraz wszechstronnego testowania. Pamitaj, e jeli program wielowtkowy
czasami zawiesza si, to najbardziej prawdopodobn tego przyczyn jest wanie zakleszczenie.
Sytuacja wycigu wystpuje, gdy dwa (lub wicej) wtków próbuje uzyska równoczenie dostp do
wspódzielonego zasobu, ale odbywa si to bez odpowiedniej synchronizacji. Na przykad jeden wtek
moe przypisywa zmiennej now warto, podczas gdy inny wtek w tym samym czasie zwiksza
warto tej samej zmiennej. Jeli nie zastosujemy synchronizacji, to wynik tych operacji bdzie zale-
e od kolejnoci wykonania wtków (czy drugi wtek najpierw zwikszy oryginaln warto zmien-
nej, czy raczej pierwszy wtek zdy przypisa jej wczeniej now warto?). W takich sytuacjach
mówi si o wycigu wtków, poniewa ostateczny wynik operacji zaley od tego, który wtek bdzie
pierwszy. Podobnie jak w przypadku zakleszczenia wykrycie sytuacji wycigu moe by trudne. Naj-
lepszym rozwizaniem jest zapobieganie: staranne programowanie z zastosowaniem odpowiedniej
synchronizacji dostpu do wspódzielonych zasobów.
Wstrzymywanie, wznawianie
i koczenie dziaania wtków
Moliwo wstrzymania wykonywania wtku bywa przydatna w pewnych sytuacjach. Na
przykad osobny wtek moe wywietla czas. Jeli uytkownik nie chce oglda zegara,
wtedy mona wstrzyma dziaanie wtku, który go wywietla. Niezalenie od przyczyny wstrzy-
manie wykonywania wtku nie powinno stanowi problemu. Podobnie jak póniejsze wzno-
wienie jego dziaania.
Mechanizm wstrzymywania, wznawiania i koczenia dziaania wtków róni si we wcze-
snych i obecnych wersjach Javy. W wersjach wczeniejszych ni Java 2 do wstrzymywania,
wznawiania i koczenia dziaania wtków suyy odpowiednio metody
suspend()
,
resume()
i
stop()
zdefiniowane w klasie
Thread
. Maj one nastpujc posta:
final void resume( )
final void suspend( )
final void stop( )
Mimo e metody te wydaj si waciwym rozwizaniem kwestii zarzdzania wykonaniem
wtków, obecnie ich uycie nie jest zalecane. W Javie 2 uznano metod
suspend()
klasy
Thread
za przestarza. Powodem bya moliwo doprowadzenia w pewnych sytuacjach do
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
393
zakleszcze na skutek uycia tej metody. Metod
resume()
równie uznano za przestarza. Nie
powodowaa ona adnych problemów, ale jej uycie bez metody
suspend()
nie miao sensu.
Metod
stop()
równie uznano za przestarza w Javie 2, poniewa w pewnych warunkach
jej uycie mogo by przyczyn powanych problemów.
Skoro nie mona ju uywa metod
suspend()
,
resume()
i
stop()
do sterowania dziaaniem
wtku, mogoby si wydawa, e nie ma sposobu, by wstrzyma, wznowi lub zakoczy
wykonywanie wtku. Nic bardziej bdnego. Wystarczy zaprojektowa wtek w taki sposób,
aby metoda
run()
sprawdzaa okresowo, czy powinna wstrzyma, wznowi lub zakoczy
swoje dziaanie. Zwykle osiga si to przez wprowadzenie w klasie wtków dwóch znaczników:
jednego dla wstrzymania i wznowienia wtku i drugiego dla zatrzymania wtku. W przypadku
operacji wstrzymania i wznowienia wtku, jeli odpowiedni znacznik nie jest ustawiony,
metoda
run()
musi kontynuowa wykonywanie wtku. W przeciwnym razie musi wstrzyma
swoje dziaanie. Jeli ustawiony jest drugi ze znaczników, oznaczajcy zatrzymanie wtku,
metoda
run()
musi zakoczy dziaanie.
Na listingu 11.11 przedstawiem jeden ze sposobów implementacji wasnych wersji metod
suspend()
,
resume()
i
stop()
.
Listing 11.11.
Suspend.java
// Wstrzymywanie, wznawianie i zatrzymywanie wtku.
class MyThread implements Runnable {
Thread thrd;
boolean suspended;
Powoduje wstrzymanie wykonania wtku, gdy ma warto
true.
boolean stopped;
Powoduje zakoczenie wykonania wtku, gdy ma warto
true.
MyThread(String name) {
thrd = new Thread(this, name);
suspended = false;
stopped = false;
thrd.start();
}
// Punkt wejcia do wtku.
public void run() {
System.out.println(thrd.getName() + " rozpoczyna dziaanie.");
try {
for(int i = 1; i < 1000; i++) {
System.out.print(i + " ");
if((i%10)==0) {
System.out.println();
Thread.sleep(250);
}
// Uywa bloku synchronized, aby sprawdzi
// wartoci skadowych suspended i stopped.
synchronized(this) {
Ten blok
synchronized sprawdza wartoci skadowych
while(suspended) {
suspended i stopped.
wait();
}
if(stopped) break;
}
Poleć książkę
Kup książkę
394
Java. Przewodnik dla pocztkujcych
}
} catch (InterruptedException exc) {
System.out.println(thrd.getName() + " zosta przerwany.");
}
System.out.println(thrd.getName() + " koczy dziaanie.");
}
// Zatrzymuje wtek.
synchronized void mystop() {
stopped = true;
// Ponisze instrukcje umoliwiaj zatrzymanie wtku,
// którego wykonanie zostao wstrzymane.
suspended = false;
notify();
}
// Wstrzymuje dziaanie wtku.
synchronized void mysuspend() {
suspended = true;
}
// Wznawia dziaanie wtku.
synchronized void myresume() {
suspended = false;
notify();
}
}
class Suspend {
public static void main(String args[]) {
MyThread ob1 = new MyThread("Wtek potomny klasy MyThread");
try {
Thread.sleep(1000); // umoliwia rozpoczcie wykonywania wtku ob1
ob1.mysuspend();
System.out.println("Wstrzymuj wtek.");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Wznawiam wtek.");
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Wstrzymuj wtek.");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Wznawiam wtek.");
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Zatrzymuj wtek.");
ob1.mystop();
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
395
} catch (InterruptedException e) {
System.out.println("Wtek gówny zosta przerwany");
}
// czeka na zakoczenie wtku
try {
ob1.thrd.join();
} catch (InterruptedException e) {
System.out.println("Wtek gówny zosta przerwany");
}
System.out.println("Wtek gówny koczy dziaanie.");
}
}
Poniej przedstawiem rezultat dziaania programu (moe nieco róni si w Twoim przypadku).
Wtek potomny klasy MyThread rozpoczyna dziaanie.
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
Wstrzymuj wtek.
Wznawiam wtek.
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
Wstrzymuj wtek.
Wznawiam wtek.
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100
101 102 103 104 105 106 107 108 109 110
111 112 113 114 115 116 117 118 119 120
Zatrzymuj wtek.
Wtek potomny klasy MyThread koczy dziaanie.
Wtek gówny koczy dziaanie.
Program ten dziaa w nastpujcy sposób. Klasa
MyThread
definiuje dwie zmienne typu
boolean
o nazwach
suspended
i
stopped
, które zarzdzaj operacjami wstrzymania i zatrzymania wtku.
Konstruktor klasy
MyThread
nadaje tym zmiennym warto pocztkow
false
. Metoda
run()
zawiera blok
synchronized
, który sprawdza warto zmiennej
suspended
. Jeli jest ona równa
true
, wywouje metod
wait()
, aby wstrzyma dziaanie wtku. Aby wstrzyma dziaanie
wtku, wywoujemy metod
mysuspend()
, która nadaje zmiennej
suspended
warto
true
.
Aby wznowi wtek, wywoujemy metod
myresume()
, która nadaje zmiennej
suspended
warto
false
i wywouje metod
notify()
.
Aby zakoczy wtek, wywoujemy metod
mystop()
, która nadaje zmiennej
stopped
warto
true
. Dodatkowo metoda
mystop()
nadaje zmiennej
suspended
warto
false
, a nastpnie
wywouje metod
notify()
. Jest to konieczne, aby zakoczy wtek, którego wykonanie zostao
wczeniej wstrzymane.
Poleć książkę
Kup książkę
396
Java. Przewodnik dla pocztkujcych
Ekspert odpowiada
Pytanie: Wielowtkowo wydaje si by doskonaym sposobem poprawy efektywnoci moich
programów. Czy moesz poda wskazówk, jak najefektywniej korzysta z tego mechanizmu?
Odpowied: Klucz do efektywnego wykorzystania wielowtkowoci polega na przestawieniu si z myle-
nia kategoriami sekwencyjnego dziaania na bardziej równolege. Na przykad gdy w Twoim progra-
mie istniej dwa podsystemy dziaajce zupenie niezalenie od siebie, powiniene powanie rozwa-
y moliwo zaimplementowania ich jako osobnych wtków. Jedno sowo przestrogi. Jeli stworzysz
zbyt wiele wtków, moesz pogorszy efektywno dziaania programu, zamiast j poprawi. Pami-
taj o narzucie zwizanym z przeczaniem kontekstu wykonania wtków. Jeli Twój program uru-
chomi zbyt wiele wtków, wikszo czasu procesora zajmie przeczanie kontekstu wtków, a nie
wykonanie programu!
Przykad 11.2.
Wykorzystanie gównego wtku
Wszystkie programy w Javie maj przynajmniej jeden wtek wykonania zwany
wtkiem gównym. Wtek ten powstaje automatycznie w momencie uruchomienia
programu. Jak dotd zaniedbywalimy istnienie wtku gównego, ale w tym przykadzie prze-
konasz si, e mona si nim posugiwa tak jak kadym innym wtkiem.
1.
Utwórz plik o nazwie UseMain.java.
2.
Dostp do wtku gównego wymaga uzyskania obiektu typu
Thread
reprezentujcego
ten wtek. W tym celu wywoamy metod
currentThread()
zadeklarowan jako
static
w klasie
Thread
. Jej ogóln posta przedstawiem poniej:
static Thread currentThread()
Metoda ta zwraca referencj wtku, w którym zostaa wywoana. Zatem jeli wywoamy
j w gównym wtku, otrzymamy referencj gównego wtku. Dysponujc t referencj,
moemy kontrolowa dziaanie gównego wtku w taki sam sposób jak innych wtków.
3.
Wprowad w pliku tekst ródowy programu przedstawiony na listingu 11.12. Program
ten pobiera referencj wtku gównego, a nastpnie zmienia jego nazw i priorytet.
Listing 11.12.
UseMain.java
/*
Przykad 11.2
Sterowanie wtkiem gównym.
*/
class UseMain {
public static void main(String args[]) {
Thread thrd;
// Pobiera referencj wtku gównego.
thrd = Thread.currentThread();
// Wywietla nazw wtku gównego.
System.out.println("Nazwa wtku gównego: " +
thrd.getName());
UseMain.java
Poleć książkę
Kup książkę
Rozdzia 11.
i Programowanie wielowtkowe
397
// Wywietla priorytet wtku gównego.
System.out.println("Priorytet wtku gównego: " +
thrd.getPriority());
System.out.println();
// Konfiguruje nazw i priorytet wtku gównego.
System.out.println("Zmieniam nazw i priorytet wtku gównego.\n");
thrd.setName("Wtek nr 1");
thrd.setPriority(Thread.NORM_PRIORITY+3);
System.out.println("Aktualna nazwa wtku gównego: " +
thrd.getName());
System.out.println("Biecy priorytet wtku gównego: " +
thrd.getPriority());
}
}
4.
Poniej przedstawiem wynik dziaania tego programu:
Nazwa wtku gównego: main
Priorytet wtku gównego: 5
Zmieniam nazw i priorytet wtku gównego.
Aktualna nazwa wtku gównego: Wtek nr 1
Biecy priorytet wtku gównego: 8
5.
Wykonujc operacje na wtku gównym, powiniene zachowa ostrono. Na przykad:
jeli umiecisz na kocu metody
main()
kod przedstawiony poniej, to program nigdy
nie zakoczy swojego dziaania, poniewa bdzie oczekiwa na zakoczenie wtku
gównego!
try {
thrd.join();
} catch(InterruptedException exc) {
System.out.println("Wtek przerwany");
}
Test sprawdzajcy
1.
W jaki sposób wielowtkowo w Javie umoliwia tworzenie efektywniejszych
programów?
2.
Wielowtkowo w Javie opiera si na klasie _____________ i interfejsie
_____________.
3.
Dlaczego czasami, tworzc wtki, lepiej jest utworzy klas pochodn klasy
Thread
,
ni implementowa interfejs
Runnable
?
4.
Poka, jak uy metody
join()
do oczekiwania na zakoczenie wtku
MyThrd
.
Poleć książkę
Kup książkę
398
Java. Przewodnik dla pocztkujcych
5.
Zwiksz priorytet wtku
MyThrd
o trzy poziomy ponad normalny.
6.
Na czym polega efekt dodania sowa kluczowego
synchronized
w deklaracji metody?
7.
Metod
wait()
i
notify()
uywamy do _____________.
8.
Zmodyfikuj klas
TickTock
w taki sposób, aby rzeczywicie symulowaa upyw czasu.
Zatem niech kady „tik” trwa pó sekundy, podobnie „tak”. Kady tik-tak zajmie
zatem jedn sekund (nie przejmuj si czasem potrzebnym na przeczenie wtku).
9.
Dlaczego w nowych programach nie naley uywa metod
suspend()
,
resume()
i
stop()
?
10.
Jaka metoda klasy
Thread
zwraca nazw wtku?
11.
Co zwraca metoda
isAlive()
?
12.
Spróbuj samodzielnie wprowadzi synchronizacj w klasie
Queue
stworzonej
w poprzednich rozdziaach w taki sposób, aby zapewni jej bezpieczne uycie w wielu
wtkach.
Poleć książkę
Kup książkę
Skorowidz
A
abstrakcyjna klasa bazowa, 284
adnotacje, 400, 422
ogólnego przeznaczenia, 424
znacznikowe, 424
algorytm sortowania Quicksort, 212, 216
anonimowa klasa wewntrzna, 221, 521
API, Application Programming Interface, 279
aplet, 22, 464, 467
bazujcy na AWT, 470
MySwingApplet, 524
obsugujcy zdarzenia myszy, 483
Swing, 522
wywietlajcy baner, 471
aplety
architektura, 467
dziaanie, 469
parametry, 475
szkielet, 468
architektura
model-delegat, 493
model-widok-nadzorca, 493
z wydzielonym modelem, 493
argument, 127
argument wieloznaczny, 438
ASCII, 53, 339
asercje, 488
automatyczne
konwersje typów, 71
opakowywanie, 413, 415, 418
wypakowywanie, 413
zarzdzanie zasobami, 312, 336
AWT, Abstract Window Toolkit, 464, 492
B
bajt, 334
bezpieczestwo, 23, 25
biblioteka klas, 48, 279
biblioteka Swing, 464, 491
bit, 176
bitowe operatory przypisania, 181
blok
finally, 309, 332
kodu, 43
static, 215
synchronized, 384
try, 299, 304, 312, 332
blokada, 381
bd
otwarcia pliku, 334
niejednoznacznoci, 227, 457
przekroczenia zakresu, 300
skadni, 34
w kodzie programu, 297
wewntrzne, 297
bufor, 80, 353
buforowanie wierszy, 80
C
ciao metody, 123
czas istnienia zmiennej, 62
D
definiowanie klasy, 32, 117
definiowanie pakietu, 270
deklaracja
bloku static, 215
klasy generycznej, 434
klasy pochodnej, 232
tablicy, 146, 155
zmiennej, 36
dekoder, 353
dekrementacja, 42, 65
delegacja zdarze, 481
delegat interfejsu uytkownika, 493
destruktor, 140
Poleć książkę
Kup książkę
582
Java. Przewodnik dla pocztkujcych
dodawanie konstruktora do klasy, 137
dopenienie do dwóch, 180
dostp
do pakietu, 274
do pliku, 343
do skadowych, 190, 232, 273
do skadowych klasy bazowej, 240
do systemu, 34
sekwencyjny, 343
drzewo hierarchii, 579
dynamiczne zarzdzanie pamici, 139
dynamiczno, 25
dynamiczny wybór metody, 255
dziedziczenie, 28, 230, 232, 235, 241
dziedziczenie wielobazowe, 232
dzielenie przez zero, 68, 185
E
Eclipse, 29
etykieta, 104
etykieta done, 105
etykieta jlabContents, 509
F
faszywe przebudzenie, 387
funkcje wirtualne, 256
G
generowanie wyjtku, 305
generyczna klasa Queue, 448
generyczno, 427
graficzny interfejs uytkownika, 467
H
hermetyzacja, 27
hermetyzowanie tablicy, 192
hierarchia
dziedziczenia, 28
klas, 230, 241
wielopoziomowa klas, 244
wyjtków, 296
zawierania, 494
I
IDE, 29
identyfikator, 47
implementacja, 279
implementacja interfejsu, 281
import skadowej Static.out, 422
import skadowych statycznych, 400, 420
importowanie pakietu, 278
inicjalizacja, 90
dynamiczna, 60
obiektu, 206
tablic wielowymiarowych, 153
zmiennej, 59
inicjalizator, 62
inkrementacja, 42, 65
instrukcja
break, 86, 102
break z etykiet, 104
continue, 108
continue z etykiet, 108
default, 85, 89
for, 41
goto, 104
if, 40, 81
if-else-if, 83
import, 277
import static, 422
new, 120, 136
package, 270
println(), 36
return, 124
super(), 238
switch, 84, 85, 172
throw, 297
try, 338
instrukcje
iteracji, 79
skoku, 79
wyboru, 79
interfejs, 269, 279
ActionListener, 504
Annotation, 423
AutoCloseable, 336
Closeable, 336
Containment, 447
DataInput, 339
ListSelectionListener, 514
ListSelectionModel, 513
MouseListener, 482
MouseMotionListener, 482
Queue, 286
Runnable, 366
Series, 283
interfejsy
dziedziczce, 291
generyczne, 445
suchaczy zdarze, 482
interpreter kodu bajtowego, 24, 31
interpretowalno, 25
iteracja, 41
Poleć książkę
Kup książkę
Skorowidz
583
J
J2SE, Java 2 Standard Edition, 14
Java API, 279
Java SE, 15
JDK, Java Development Kit, 17, 29
jzyk C i C++, 21
jzyk C#, 22
JFC, Java Foundation Classes, 492
JIT, just-in-time, 24
JVM, Java Virtual Machine, 24
K
kana, 353
klasa, 27, 115
ActionEvent, 503, 504
Applet, 477
ArithmeticException, 300
Book, 274
BookDemo, 274
BufferedReader, 348, 352
ByThrees, 283
ByTwos, 281
CircularQueue, 287
Component, 470, 495
Console, 345
Container, 495
DataInputStream, 339
DataOutputStream, 339
Error, 296
ErrorInfor, 199
ErrorMsg, 265
Exception, 296
FailSoftArray, 192
FileInputStream, 330
FileOutputStream, 330, 334
FileReader, 351
FileWriter, 350
GenericMethodDemo, 443
Help, 130
InputStream, 328
InputStreamReader, 352
ItemEvent, 509
JApplet, 522
java.lang.Enum, 406
JButton, 506
JCheckBox, 509
JComponent, 494
JList, 512
JTextField, 506
ListSelectionEvent, 513
Math, 53, 420
MyThread, 367, 395
NonIntResultException, 316
NumericFns, 435
Object, 267
OutputStreamWriter, 351
Pair, 437
PrintWriter, 349
Pwr, 143
Queue, 158, 194, 207, 448
Quicksort, 217
RandomAccessFile, 343
Reader, 352
RuntimeException, 313
Scanner, 360
ShowBits, 182, 221
SimpleApplet, 465
String, 167
StringBuffer, 171
Summation, 445
Sup, 256
System, 48, 279, 326
Thread, 365, 374
Throwable, 296, 307, 315
TickTock, 389
Timer, 212
Triangle, 233, 250
TwoDShape, 231, 250, 264
Vehicle, 119
Writer, 351
klasy
abstrakcyjne, 260
bazowe, 229
generyczne, 428
komponentów Swing, 495
nadrzdne, 28
NIO, 353
opakowujce, 353–355
pochodne, 229, 232
pochodne klasy Exception, 315
pochodne klasy Thread, 370
strumieni bajtowych, 325
strumieni znakowych, 326
wewntrzne, 219, 521
zagniedone, 218
zagniedone static, 222
zdarze, 481
klauzula
case, 85
catch, 298, 302, 312
else, 81
extends, 435, 440
finally, 309
implements, 281
throws, 311
throws java.io.IOException, 80
Poleć książkę
Kup książkę
584
Java. Przewodnik dla pocztkujcych
kod bajtowy, 24
koder, 353
kodowanie, 31
kolejka, 158
kolejka cykliczna, 288
kolejka dynamiczna, 286
komentarz, 32
dokumentacyjny, 573, 578
jednowierszowy, 33
wielowierszowy, 32
kompilator, 28
kompilator javac, 31, 32
kompilator JIT, 24
kompilowanie programu, 24, 31
komponent
JButton, 502
JCheckBox, 509
JList, 512
JTextField, 506
komponenty Swing, 494
komunikacja midzywtkowa, 386
konsola znakowa, 80
konstruktor, 135
domylny, 238
generyczny, 445
klasy bazowej, 235, 238
klasy Queue, 207
klasy Thread, 369
klasy Throwable, 315
klasy Triangle, 236
klasy TwoDShape, 237
MyClass(), 206
o jednym parametrze, 238
Transport(), 405
TwoDShape(), 252
typu wyliczeniowego, 404
z parametrem, 136
kontekst graficzny, 465
kontener JApplet, 522
kontener JFrame, 522
kontenery szczytowe, 495
konwersja typów w wyraeniach, 76
konwersja typu, 71
kopiowanie pliku, 335
kopiowanie tablicy, 158
L
LIFO, last-in, first-out, 28
lista argumentów o zmiennej dugoci, 221
lista JList, 512
literay, 56
acuchowe, 58
znakowe, 59
acuch wyjtków, 315
acuch znaków, 58, 167
M
maszyna wirtualna Java, 24
meneder
BorderLayout, 501
FlowLayout, 504, 505
ukadu, 496
metadane, 422
metoda, 27, 33, 122
metoda
abs(), 205
absEqual(), 438
actionPerformed(), 509
addActionListener(), 506, 521
area(), 261
charAt(), 171
close(), 331, 334
compareTo(), 355, 406
console(), 345
destroy(), 470
doubleValue(), 414, 435
finalize(), 139
floatValue(), 414
generator(), 141
generyczna arraysEqual(), 443
genException(), 307
get(), 286
getActionCommand(), 503
getClass(), 267
getContentPane(), 500
getErrorInfo(), 199
getErrorMsg(), 199
getob(), 430
getParameter(), 475
getSelectedIndex(), 513
getSelectedIndices(), 514
getSpeed(), 405
getText(), 506
init(), 469, 485
invokeAndWait(), 501, 502
invokeLater(), 501, 502
isAlive(), 375
isFactor(), 128
join(), 375
main(), 33
makeGUI(), 524
Math.abs(), 438
Math.pow(), 420
mouseClicked(), 482
mouseDragged(), 482
Poleć książkę
Kup książkę
Skorowidz
585
mouseEntered(), 482
mouseExited(), 482
mouseMoved(), 482
noChange(), 197
notify(), 386
notifyAll(), 386
ordinal(), 406
ovlDemo(), 202
paint(), 465, 470
parseDouble(), 354
print(), 37, 349
println(), 34, 37, 349, 352
printStackTrace(), 308
prompt(), 311
put(), 286
range(), 122
read(), 80, 328
readLine(), 348
readPassword(), 345
reciprocal(), 435
removeActionListener(), 506
removeKeyListener(), 480
repaint(), 470
resume(), 392
run(), 366, 393
setActionCommand(), 506, 508
setCharAt(), 171
setName(), 369
setPriority(), 378
show(), 253
showStatus(), 475
showType(), 431
sleep(), 367
sqrt(), 53, 214
start(), 469
static, 214
stop(), 392
substring(), 171
sumArray(), 384
suspend(), 392
System.console(), 345
tick(), 387
tock(), 387
toString(), 308, 414
update(), 471
valueChanged(), 514
values(), 403
valuesOf(), 403
vaTest(), 223
vaTest(int ...), 227
wait(), 386, 391
write(), 334
metody
abstrakcyjne, 261, 279
dostpowe dla skadowych prywatnych, 233
generyczne, 443
klasy Applet, 477
klasy InputStream, 327
klasy Object, 267
klasy OutputStream, 328
klasy Reader, 346
klasy Thread, 365
klasy Throwable, 308
klasy Writer, 347
konwersji acuchów, 354
natywne, 488
o zmiennej liczbie argumentów, 222
rekurencyjne, 210
pcherzykowego, 216
wejcia klasy DataInputStream, 340
wyjcia klasy DataOutputStream, 339
model, 493
model delegacji zdarze, 479
modyfikator
abstract, 261
dostpu, 33
final, 312
private, 33, 191, 194, 232
protected, 190, 275
public, 33, 190
transient, 486
volatile, 486
modyfikatory dostpu, 190
monitor, 381
N
nadzorca, 493
najmodszy bit, 180
narzut, 420
nawias klamrowy, 34
nawiasy, 77
nazwa
klasy, 138
obiektu, 118
pliku ródowego, 30
NetBeans, 29
niejednoznaczno, 226
niezaleno, 25
niezawodno, 25
O
obiekt, 27, 116
ActionEvent, 503
klasy String, 167
przekazywany metodzie, 195
System.err, 327
System.in, 327
Poleć książkę
Kup książkę
586
Java. Przewodnik dla pocztkujcych
obiekt
System.out, 327
Thread, 369
typu Integer, 431
typu T, 437
zablokowany, 381
obiektowo, 25
obliczanie silni, 210
obsuga
bdów, 301, 317
bdów wejcia-wyjcia, 331
plików, 350
wejcia konsoli, 328
wyjtków, 295
wyjcia konsoli, 329, 349
zdarze, 479
zdarze myszy, 482
odczyt konsoli, 345
odczyt z pliku, 330
odczyt znaków, 346
odstpy, 77
odwoanie do obiektu, 120
odzyskiwanie nieuytków, 139
ogólna klasa akcji, 28
ograniczanie argumentów wieloznacznych, 440
ograniczanie typów, 434
ograniczenia dla skadowych statycznych, 458
ograniczenia tablic generycznych, 459
ograniczenia zwizane z wyjtkami, 460
okno
apletu SimpletApplet, 466
programu ListDemo, 515
programu SwingFC, 516
programu TFDemo, 508
statusu, 475
opakowywanie, 414
opcja classpath, 271
operacja bitowa z operatorem przypisania, 181
operacja get, 159
operacja put, 159
operacje na acuchach, 168
operator, 63
?, 184
+, 36
bitowy AND, 175
bitowy NOT, 179
bitowy OR, 177
bitowy XOR, 178
delete, 139
diamentowy, 456
instanceof, 486
new, 120, 138, 146
przypisania, 69, 121
ternarny, 184
operatory
arytmetyczne, 64
bitowe, 175
logiczne, 66, 67
logiczne warunkowe, 67
przesunicia bitów, 180
relacyjne, 40, 66
skrótowe przypisania, 70
zoone przypisania, 70
P
pakiet, 190, 269
AWT, 465, 477
bookpack, 272, 273
bookpackext, 275, 276
java, 279
java.awt, 504
java.awt.event, 479, 504
java.io, 312, 324
java.lang, 279
java.lang.annotation, 423
javax, 494
javax.swing.event, 513
mypack, 271
NIO, 353
Swing, 324, 493
pakiety Java API, 279
panel szklany, 495
panel warstw, 495
panel zawartoci, 495
parametr, 33, 127
parametr T, 430
parametry apletów, 475
ptla
do-while, 97
for, 41, 90, 92, 162
for rozszerzona, 166
for-each, 162, 163
while, 96
ptle
bez ciaa, 94
nieskoczone, 94
zagniedone, 112
plik
Banner.java, 471
BookDemo.java, 272
Bubble.java, 149
CompFiles.java, 341
Example.class, 31
Example.java, 30
ExtendThread.java, 371
Finalize.java, 140
GalToLit.java, 39
GalToLitTable.java, 45
Poleć książkę
Kup książkę
Skorowidz
587
GenQDemo.java, 450
Help.java, 88, 99
Help3.java, 109
HelpClassDemo.java, 130
ICharQ.java, 286
IGenQ.java, 448
IQDemo.java, 288
LogicalOpTable.java, 74
QDemo.java, 159
QDemo2.java, 207
QExcDemo.java, 317
QSDemo.java, 216
ShowBitsDemo.java, 182
Sound.java, 55
SwingFC.java, 516
TrafficLigthDemo.java, 408
TruckDemo.java, 242
UseMain.java, 396
VehicleDemo.class, 118
VehicleDemo.java, 118
pliki
.class, 270
HTML, 466
o dostpie swobodnym, 343
pomocy, 356
ródowe, 30
polimorfizm, 28, 204
pomoc, 130, 355
porównywanie plików, 341, 516
posta binarna, 176
priorytet operatorów, 74
priorytet wtku, 378
proces hermetyzacji, 414
program, 30
appletviewer, 465, 522
CopyFile, 337
do zamiany liter, 176
javadoc, 579
SwingDemo, 498
sygnalizacji wietlnej, 408
szyfrujcy, 178
wielowtkowy, 363
programowanie
obiektowe, 26
równolege, 386
strukturalne, 26
przechwytywanie
wyjtków, 300
wyjtków klas pochodnych, 303
wyjtków klasy bazowej, 303
przecianie konstruktorów, 205
przecianie metod, 201, 204, 225
przekazywanie
argumentów, 196
argumentów w gór, 247
argumentu przez referencj, 197
argumentu przez warto, 197
obiektów, 195
przenono, 23, 25
przerwanie programu, Ctrl+C, 391
przerywanie ptli, 102
przesanianie metod, 252, 255
przesanianie metod w klasie TwoDShape, 257
przesanianie nazw, 63
przestrze nazw, 270
przypisanie, 120
przypisywanie referencji tablic, 155
pusta instrukcja, 94
R
referencje, 120
interfejsu, 284
klasy bazowej, 248
obiektów klas pochodnych, 250
tablicy, 155
rekurencja, 210
rczne opakowywanie i wypakowywanie, 415
rozproszono, 25
rozszerzenie .class, 31
rozszerzenie .java, 30
rzutowanie, 442
rzutowanie typów, 72
S
schemat klasy Triangle, 231
schemat tablicy, 147
sekwencje specjalne, 57
sekwencje znaków, 57
selektor, 353
separator, 44
serwlet, 25
skadnia (...), 226
skadowa length, 156
skadowa protected, 275, 278
skadowa prywatna, 192
skadowe klasy, 27
sowo kluczowe, 47
assert, 487
class, 116
enum, 403
extends, 230, 291
false, 47
final, 264
finally, 309
import, 420
instanceof, 487
interface, 280, 423
Poleć książkę
Kup książkę
588
Java. Przewodnik dla pocztkujcych
sowo kluczowe
native, 488
null, 47
public, 33
static, 33, 212, 420
strictfp, 487
super, 237, 240, 253
synchronized, 381
this, 142, 240, 489
transient, 486
true, 47
try i catch, 297
void, 33
volatile, 486
suchacz, 480
specyfikacja zasobu, 336
staa final, 266
stae wasnego typu, 400
stae wspódzielone, 291
stae wyliczeniowe, 400, 401
sterowanie cyklem wykonania apletu, 468
sterowanie instrukcj switch, 172
stos, 28, 158
strumie, 324
bajtowy, 324, 345
bdów, 327
InputStream, 339
InputStreamReader, 345
predefiniowany, 327
wejcia, 324, 328
wyjcia, 324, 327
znakowy, 324, 345
znakowy FileReader, 352
znakowy FileWriter, 351
znakowy PrintWriter, 349
sygnatura, 205
synchronizacja, 364, 380
dostpu do metody, 381
dostpu do obiektu, 381
instrukcji, 384
metod, 381, 384
system ósemkowy, 57
system pomocy, 355
system szesnastkowy, 57
szkielet apletu, 468
cieka dostpu do katalogu, 271
rednik, 44
T
tabela prawdy, 74
tablice, 145
dwuwymiarowe, 151
jednowymiarowe, 146
acuchów, 170
nieregularne, 152
tablic, 165
typu T, 460
wielowymiarowe, 153
technologia HotSpot, 24
terminologia Javy, 25
tryb SINGLE_SELECTI, 513
tworzenie
adnotacji, 423
aplikacji Swing, 497, 522
instancji T, 458
acuchów, 167
obiektu, 117
przycisku, 503
wtku, 365
wielu wtków, 372
typ
interfejsu generycznego, 447
logiczny, 54
surowy, 452
surowy klasy generycznej, 453
wyliczeniowy, 404
zmiennej, 36
zmiennej referencyjnej, 250
typy
cakowite, 51
danych, 37, 50
generyczne, 413, 432
ogólne, 267
opakowujce, 414
podstawowe, 139
zmiennoprzecinkowe, 52
U
Unicode, 53
ustawianie bitu, 176
W
warto null, 348
warto porzdkowa, 407
warto zmiennych, 62
wtek, 363
gówny, 365, 369, 396
gotowy do wykonywania, 364
koczcy dziaanie, 376, 392
potomny, 375
priorytet, 378
rozdziau zdarze, 501
wstrzymujcy dziaanie, 392
wykonywany, 364
wznawiajcy dziaanie, 392
Poleć książkę
Kup książkę
Skorowidz
589
zablokowany, 364
zakoczony, 364
zawieszony, 364
wczytywanie acuchów, 348
widok, 493
wielowtkowo, 25, 364, 396
wielozadaniowo, 364
wiersz wywoania, 173
wnioskowanie typów, 456
wskanik, 26
wskanik zawartoci pliku, 343
wycieki pamici, 331
wyjtek, 295
ArithmeticException, 301, 313
ArrayIndexOutOfBoundsException, 149, 298, 300,
304, 313
AssertionError, 487
FileNotFoundException, 334
IOException, 311, 328
wyjtki
niesprawdzane, 314
sprawdzane, 314
w klasie Queue, 317
wbudowane w Jav, 313
wyliczanie wartoci, 220
wyliczenie, 400
wymazywanie, 457
wyraenia, 75
wycig, 392
wywoanie
konstruktora klasy bazowej, 237
super.show(), 254
System.in.read(), 80
this(), 489
konstruktorów, 247
Z
zagniedanie
bloków, 62
bloków try, 304
instrukcji if, 82
instrukcji switch, 88
zasigów, 61
zakleszczenie, 392
zamknicie pliku, 332
zamykanie automatyczne pliku, 336
zapis danych, 329
zapis w pliku, 334
zapis znaków w pliku, 350
zapobieganie dziedziczeniu, 265
zapobieganie przesanianiu, 264
zasig deklaracji, 95
zasig deklaracji zmiennych, 60
zbiór znaków, 353
zdarzenia, 479
klasy, 480
model delegacji, 481
suchacze, 480
róda, 479
zdarzenie ListSelectionEvent, 513, 514
zintegrowane rodowisko programisty, 29
zmienna, 27, 35, 59
final, 406
iteracyjna, 162, 165
minivan, 120
referencyjna, 248, 285
sterujca, 93
rodowiskowa CLASSPATH, 271
zmienne interfejsu, 280
znacznik APPLET, 465
znacznik OBJECT, 466
znaczniki javadoc, 573
znak +, 36
znak komentarza, 277
znaki, 53
zwracanie obiektów, 199
zwracanie wartoci, 125
róda zdarze, 479
Poleć książkę
Kup książkę
590
Java. Przewodnik dla pocztkujcych
Poleć książkę
Kup książkę