Przesuwamy się ku coraz trudniejszym tematom języka Java i tym razem rozpocznę serię artykułów dotyczących wątków. Wątek w Java jest już zaawansowanym rozdziałem w programowaniu i nawet doczekał się własnego działu naukowego, "programowanie współbieżne". Bez względu na wszystko, trzeba zacząć od samego początku i najpierw wyjaśnić sobie teorię zanim przejdziemy do części praktycznej. Zapraszam serdecznie do wpisu.

WĄTEK W JAVA TO TRUDNY WĄTEK DO OPANOWANIA

Żadne odkrycie, aczkolwiek wszystko co na tym świecie jest trudne, nie jest awykonalne. Rozpocznijmy od definicji: wątek to osobny, niezależny stos wywołań wykonujący się równolegle razem z "głównym" stosem (zapoczątkowanym przez statyczną metodę "main"). Pozwala on na wykonywanie innego przydzielonego zadania, który w założeniach programisty musi przebiegać niezależnie od jedynego "ciągu" wykonywanych poleceń. Pamiętacie zapewne jak działa stos wywołań metod. To wyobraźcie sobie teraz, że tworząc nowy wątek w Java, powstaje drugi taki stos położony tuż obok pierwszego i oba idą własnym tokiem nie przeszkadzając sobie nawzajem, choć mogą od siebie wymagać pewnych wyników, o czym piszę poniżej.

ZNANE PROBLEMY PRZY KORZYSTANIU Z WĄTKÓW

Temat ten robi się o wiele bardziej skomplikowany gdy używa się go w praktyce. Jednym ze znanych problemów jest spójność danych. Chodzi o sytuację w której dwa osobne procesy operują na tej samej danej. Mimo tego, że wątek w Java to osobny stos wywołań, to jednak pożądanym zawsze jest operowanie na tych samych zmiennych oraz żeby ich modyfikacje były trwałe i miały wpływ na dalszy ciąg postępowania innego procesu. Być może niektórzy z Was kojarzą słowo kluczowe w języku C, "volatile". W dawnych czasach stanowiło to powszechnie stosowaną ochronę przed przyjmowaniem indywidualnych wartości przez każdy wątek. W praktyce, gdy jakaś zmienna była dla przykładu równa 7 i przyjmowała taką samą wartość dla wielu wątków, to gdy w jednym z nich wykonywana była dowolna modyfikacja (np. preinkrementacja), to ta zmiana była trwała i dotyczyła całej reszty wątków. W przeciwnym razie, po zakończeniu wątku, który modyfikował tę liczbę, zmienna dalej byłaby "siódemką" i nie byłoby śladu po tej modyfikacji. Traktujcie ten przypadek jako abstrakcyjne uproszczenie tego dylematu w nadziei, że wiecie o co chodzi.

Zmienna ulotna - wątek w Java

Zmienna "ulotna" ("volatile") wykorzystywana jest podczas współbieżności w celu utrwalenia modyfikacji danych jednego z wątków, aby ta sama wartość obowiązywała dla całej reszty zadań.

Drugi znany problem to ryzyko zakleszczenia się wątków. Wątek w Java też może tego doświadczyć. Wykonują się co najmniej dwa zadania równolegle i dochodzi do momentu, w którym działanie jednego wątku jest zależne od drugiego i na odwrót. Jeden wątek wykonuje jakieś zadanie. W momencie gdy zaczął go wykonywać został na chwilę "wstrzymany" (ale dalej "siedzi" w środku tego zadania). Drugi wątek teraz ma prawo działać i wykonuje jakieś inne zadanie, ale jest ono powiązane z zadaniem wątku pierwszego. Obecnie działający wątek jest usypiany, czeka na pomyślne wykonanie zadania wątku pierwszego. Wtedy do akcji powraca wątek pierwszy, który nie skończył swojego zadania i już go nie skończy, ponieważ podstawą do zakończenia swojego działania jest wywołanie jednej z metod dotyczących zadania przeprowadzanego przez wątek sąsiedni. Dochodzi do "zakleszczenia się" wzajemnie obu wątków, gdyż zadanie "sąsiada" ma wpływ na kontynuację swojego zadania. Nic przyjemnego, prawda?

Zakleszczenie wątków

Wzajemna blokada wątków pojawia się w sytuacji, gdy dwa lub więcej wątków nie może zakończyć swojego zadania z powodu powstałej zależności od innego wątku, który on sam również wymaga zakończenia zadań u "sąsiada".

Wątek w Java posiada nieco szersze wsparcie i choć to samo słowo kluczowe "volatile" również występuje do tych samych celów, to można też skorzystać z mechanizmu synchronizacji. Ten artykuł dokładnie opisuje proces metod synchronizowanych razem z przykładowym kodem źródłowym. Na zakończenie dodam jeszcze, że język umożliwia symulację współbieżnego działania programu nawet na procesorach jednordzeniowych! To znaczy, że choć komputer fizycznie nie posiada możliwości wykonywania wielu zadań jednocześnie, to Javie to nie robi różnicy i maszyna wirtualna będzie w stanie wiarygodnie "udawać" procesor wielordzeniowy.


Na sam wstęp do programowania współbieżnego widziałbym tyle podstawowych informacji. Jeśli rozumiecie teorię dosyć dobrze, to dopiero wtedy możecie zabrać się za kolejny artykuł.

PODOBNE ARTYKUŁY