Cześć!
Ostatnim tematem programistycznym, który poruszałem były aspekty programowania reaktywnego w Javie. Przedstawiłem ogólną koncepcję programowania reaktywnego oraz opisałem Spring WebFlux dostarczając kilka innych przykładów. Ciągnąc dalej tematy reaktywne, na pewno przyda nam się pojęcie wątków. W związku z tym chciałbym rozpocząć serię o wątkach, w których powstaną posty m.in. o: wątkach ogólnie (dzisiaj), sposoby tworzenia wątków, programy wielowątkowe, pułapki związane z wątkami. Do dzieła!
Definicja
Wątek to niezależny, osobny stos wywołań wykonujący się równolegle razem z „głównym „stosem”.
Innymi słowy, wątek pozwala na wykonanie przydzielonego zadania, który w założeniach przebiega całkowicie niezależnie.
Definicja praktyczna
Moim zdaniem pojęcie wątku najlepiej zrozumieć w przypadku gdy…nie ma wątków. Wyobraźmy sobie w praktyce, że dla osiągnięcia jednego swojego celu potrzebujemy wykonania trzech kroków, zadań. W przypadku programu bez wątków, wykonanie tego celu wyglądałoby tak, że każde z kroków uruchomi się sekwencyjnie na jednym procesorze. Co to znaczy? Że krok B będzie czekał, aż skończy się krok A, a krok C będzie czekał, aż skończy się krok A oraz B. Innymi słowy: zadania uruchamiane są po kolei.
Tworzenie wątku
Istnieją trzy popularne metody tworzenia wątków:
- dziedziczenie po klasie Thread
- implementacja interfejsu Runnable
- implementacja interfejsu Callable
Dlatego, że jest to pierwszy post, dzisiaj chciałbym omówić jedynie ten pierwszy sposób tworzenia wątku, czyli dziedziczenia po klasie Thread. Oto jak to się robi:

Jak widać, nastąpiło nadpisanie metody run(), to właśnie w jej ciele zostaje wykonane ciało wątku.
Cykl życia wątku
Warto wiedzieć, że każdy wątek ma swój cykl życia. Mówi się o sześciu stanach, w których wątek może się znaleźć (w środowisku programistycznym możemy podejrzeć to w klasie wyliczeniowej Thread.State):
- NEW – nowy wątek, który nie może wykonywać kodu ponieważ nie został uruchomiony
- RUNNABLE – wątek, który już może wykonywać swój kod
- TERMINATED – wątek, który się zakończył
- BLOCKED – wątek który oczekuje na zwolnienie zasobów
- WAITING – wątek który jest w spoczynku (sleep)
- TIMED_WAITING – wątek, który uśpiony jest na określony już z góry czas.
Warto zobaczyć sobie jak to przedstawia się graficzne:

Uważam, że każdy stan wątku warto opisać, dlatego poświęcę temu osobny post.
Przerywanie wątku
Wątek w każdym momencie można przerwać. Dzieje się tak po wywołaniu na jego instancji metodę Thread.interrupt(). Kiedy wątek zostaje przerwany, ustawia się na nim specjalna flaga, informująca nas o obecnym stanie. Można również w każdej chwili sprawdzić, czy wątek aktualnie jest przerwany, wywołując na jego instancji metodę Thread.interrupted(). Metoda zwróci true, jeśli wątek był przerywany.
Podsumowanie
Uważam, że na dobry początek teorii wystarczy. Przebernęliśmy przez podstawy podstaw. Większość z Was pewnie doskonale sobie zdaje sprawę z istnienia wątków lecz uważam, że jest to na tyle skomplikowany temat że trzeba zacząć opisywać je od podstaw. Tematyką następnego postu będzie tworzenie wątków poprzez interfejs Runnable oraz Callable (oraz podstawowe różnice między nimi) oraz pojęcie wielowątkowości.
Pozdrawiam serdecznie,
biegajacyprogramista.pl