Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

Podobne dokumenty
Wątek - definicja. Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

Współbieżność w środowisku Java

Współbieżność w Javie

Współbieżność w Javie

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Stworzenie klasy nie jest równoznaczne z wykorzystaniem wielowątkowości. Uzyskuje się ją dopiero poprzez inicjalizację wątku.

Autor: dr inż. Zofia Kruczkiewicz, Programowanie aplikacji internetowych 1

Kurs programowania. Wykład 8. Wojciech Macyna. 10 maj 2017

Programowanie równoległe i rozproszone. Monitory i zmienne warunku. Krzysztof Banaś Programowanie równoległe i rozproszone 1

Kurs programowania. Wykład 8. Wojciech Macyna

Wątki w Javie. Piotr Tokarski

Programowanie równoległe i rozproszone. W1. Wielowątkowość. Krzysztof Banaś Programowanie równoległe i rozproszone 1

Java. Wykład. Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ

Język Java wątki (streszczenie)

Wielowątkowość mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

Przetwarzanie wielowątkowe przetwarzanie współbieżne. Krzysztof Banaś Obliczenia równoległe 1

Programowanie komputerów

Programowanie wielowątkowe. Tomasz Borzyszkowski

Programowanie współbieżne i rozproszone

Wprowadzenie do programowania współbieżnego

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Obliczenia równoległe i rozproszone w JAVIE. Michał Kozłowski 30 listopada 2003

1 Wątki 1. 2 Tworzenie wątków 1. 3 Synchronizacja 3. 4 Dodatki 3. 5 Algorytmy sortowania 4

Wątki. Definiowanie wątków jako klas potomnych Thread. Nadpisanie metody run().

Semafor nie jest mechanizmem strukturalnym. Aplikacje pisane z użyciem semaforów są podatne na błędy. Np. brak operacji sem_post blokuje aplikację.

Podstawy współbieżności

Semafor nie jest mechanizmem strukturalnym. Aplikacje pisane z użyciem semaforów są podatne na błędy. Np. brak operacji sem_post blokuje aplikację.

Wielowątkowość. Programowanie w środowisku rozproszonym. Wykład 1.

Język Java wątki (streszczenie)

Języki i Techniki Programowania II. Wykład 7. Współbieżność 1

Aplikacje w Javie- wykład 11 Wątki-podstawy

Systemy operacyjne. Zajęcia 11. Monitory

Język Java część 2 (przykładowa aplikacja)

SOP2 - semafory. grudzień

Java. Programowanie Obiektowe Mateusz Cicheński

Proces z sekcją krytyczną. Synchronizacja procesów. Synchronizacja procesów, cd. Synchronizacja procesów, cd. Synchronizacja procesów, cd

Multimedia JAVA. Historia

Java Collections Framework

Monitory. Jarosław Kuchta

Programowanie współbieżne Wykład 2. Rafał Skinderowicz

WIELOWĄTKOWOŚĆ. Waldemar Korłub. Platformy Technologiczne KASK ETI Politechnika Gdańska

java.util.* :Kolekcje Tomasz Borzyszkowski

WSPÓŁBIEŻNOŚĆ. MATERIAŁY:

Wykład 4. Synchronizacja procesów (i wątków) cześć I. Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB

Problemy czytelników i pisarzy oraz 5 ucztujących filozofów

Mechanizmy pracy równoległej. Jarosław Kuchta

Równoległość i współbieżność

Równoległość i współbieżność

Programowanie współbieżne Wykład 10 Synchronizacja dostępu do współdzielonych zasobów. Iwona Kochańska

Interfejsy w Java. Przetwarzanie równoległe. Wątki.

Zadanie polega na stworzeniu bazy danych w pamięci zapewniającej efektywny dostęp do danych baza osób.

Programowanie współbieżne Wykład 5. Rafał Skinderowicz

Programowanie współbieżne Laboratorium nr 11

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Systemy operacyjne III

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Wydział Fizyki i Informatyki Stosowanej, Uniwersytetu Łódzkiego Łódź. Java podstawy języka, wykład 4 1

Programowanie współbieżne Wykład 7. Iwona Kochaoska

Wykład 8: klasy cz. 4

Proces z sekcją krytyczną. Synchronizacja procesów. Synchronizacja procesów, cd. Synchronizacja procesów, cd. Synchronizacja procesów, cd

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Programowanie Równoległe i Rozproszone

Programowanie obiektowe

Przeplot. Synchronizacja procesów. Cel i metody synchronizacji procesów. Wątki współbieżne

Wstęp do programowania 2

1 Atrybuty i metody klasowe

4. Procesy pojęcia podstawowe

Zaawansowane programowanie w C++ (PCP)

Platformy Programistyczne Podstawy języka Java

6.1 Pojęcie wątku programu 6.2 Klasy Timer, TimerTask 6.3 Klasa Thread 6.4 Synchronizacja pracy wątków 6.5 Grupowanie wątków

Programowanie obiektowe

procesów Współbieżność i synchronizacja procesów Wykład prowadzą: Jerzy Brzeziński Dariusz Wawrzyniak

Programowanie współbieżne i rozproszone w języku Java

Marcin Luckner Politechnika Warszawska Wydział Matematyki i Nauk Informacyjnych

Model pamięci. Rafał Skinderowicz

Aplikacje w środowisku Java

5. Model komunikujących się procesów, komunikaty

Programowanie współbieżne Zadanie 5 - Podstawowe problemy programowania współbieżnego

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Systemy Operacyjne synchronizacja i komunikacja procesów

1. Język JAVA. 1. Pierwszy program. 2. Kalkulator. 3. Klasy. 4. Dziedziczenie

Współbieżność w Javie. Dariusz Wawrzyniak 1. Dziedziczenie z klasy Thread definicja klasy pochodnej od Thread,

Lock Manager Deadlock Źródła Jak starczy czasu. Dreadlocks. Konrad Błachnio MIMUW 19 maja 2010

Język Java część 2 (przykładowa aplikacja)

Programowanie współbieżne Wykład 4. Rafał Skinderowicz

Klasy Obiekty Dziedziczenie i zaawansowane cechy Objective-C

4. Procesy pojęcia podstawowe

Technologie i usługi internetowe cz. 2

Programowanie obiektowe

Szablony klas, zastosowanie szablonów w programach

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Klasyczne problemy współbieżności. Problem producenta i konsumenta Problem czytelników i pisarzy Problem pięciu filozofów

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Klient-Serwer Komunikacja przy pomocy gniazd

Klasy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 13

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Synchronizacja procesów i wątków

WYKŁAD 4 SEMAPHORES (CIĄG DALSZY) Przykład 6 Problem czytelników i pisarzy. Wykład 4 strona 1/24

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Transkrypt:

Wątki

Wątek - definicja Ciąg instrukcji (podprogram) który może być wykonywane współbieżnie (równolegle) z innymi programami, Wątki działają w ramach tego samego procesu Współdzielą dane (mogą operować na tych samych danych) -> programowanie rozproszone ze współdzieleniem pamięci Obsługą wątków zajmuje się dany proces a nie system (obsługą procesów zajmuje się system) Przykład Wykorzystanie kilku rdzeni procesora jednocześnie Zrównoleglenie obliczeń Jednoczesna obsługa ekranu i procesu obliczeniowego

Implementacja wątków w Javie Wątki wymagają menadżera wątków procedury przydzielającej i dbającej o kolejność wykonywania wątków. W Javie jest to zaimplementowane wewnątrz JVM Możliwe są dwa sposoby tworzenia programów wielowątkowych Poprzez dziedziczenie po klasie Thread Poprzez implementację interfejsu Runnable

Dziedziczenie po klasie Thread Musimy wówczas przeciążyć metodę run: Uruchomienie osobnego wątku:

Implementacja Runnable Musimy wówczas zdefiniować metodę run: Uruchomienie osobnego wątku:

Metody klasy Thread Uruchamianie / Zatrzymywanie Start uruchomienie wątku Stop zatrzymanie wątku Run program wykonywany w osobnym wątku

Metody klasy Thread Uruchamianie / Zatrzymywanie Start uruchomienie wątku Stop zatrzymanie wątku Run program wykonywany w osobnym wątku Teoretycznie też działa ale tak nie wolno bo nie mamy współbieżności. Całość wykonywana jest sekwencyjnie

Ważne metody związane ze współbieżnością sleep(long ms) uśpienie wątku na określony czas wait() wprowadzenie wątku w stan oczekiwania notify()/notifyall() wzbudzenie wątku/wątków ze stanu oczekiwania Metody wait() i notify() (notifyall()) muszą być wywoływane w bloku/metodzie synchronized na tym samym obiekcie. void join([long milsec [, int nanosec]]) oczekiwanie na zakończenie wątku void setdaemon(boolean on) ustawienie wątku jako demona boolean isdaemon() czy wątek jest demonem boolean isalive() sprawdzenie czy wątek działa void interrupt(); - przerwanie działania wątku

Priorytety wątków Wątki mogą posiadać różne priorytety (ważności wykonywania) Zasada działania priorytetów: dopiero jak obsłużono wątki ważne obsługujemy wątki mniej ważne void setpriority(int priority) ustawianie priorytetu wątku, int getpriority() odczytanie priorytetu wątku. yield() oddanie czasu innym wątkom o tym samym priorytecie Stałe zdefiniowane w klasie w klasie Thread (typu final): Thread.MIN_PIORITY najniższy priorytet Thread.MAX_PIORITY maksymalny priorytet Thread.NORM_PIORITY normalny priorytet

Identyfikacja wątków String getname() pobranie nazwy wątku void setname(string name) ustawienie nazwy wątku long getid() zwrócenie identyfikatora wątku (unikatowa wartość)

Jeszcze kilka metod związanych z wątkami isalive() sprawdzenie czy wątek żyje setname(string name) nadanie wątkowi nazwy (pozwala na jego identyfikację) String getname() zwraca nazwę wątku

Wątek Demon Wątki Deamony zostają automatycznie zamknięte gdy główny program się kończy. Normalnie aplikacja działa tak długo jak działa najdłuższy wątek, i po jego zakończeniu JVM się kończy. W przypadku Deamonów tak nie jest! Metoda setdeamon(boolean) powinna być wywołana przed uruchomieniem wątku Uwaga na Deamony, bo ich zamknięcie nie powoduje wywołanie sekcji finaly co może powodować że strumienie nie zostaną poprawnie pozamykane

Wątki - problemy Często wątki korzystają ze wspólnych danych problem bezpieczeństwa danych Jednorodność danych (podczas odczytu dane nie mogą ulegać zmianie) Przykład: podczas odczytu danych przez jeden wątek drugi w międzyczasie dokonał ich modyfikacji. Współdzielone dane należy chronić przez tzw zakładanie zamka (blokowanie dojścia do danego obiektu/bloku instrukcji)

Sekcja krytyczne Sekcja krytyczna - w programowaniu współbieżnym fragment kodu programu, w którym korzysta się z zasobu dzielonego, a co za tym idzie w danej chwili może być wykorzystywany przez co najwyżej jeden wątek. i = 0 Współdzielony obszar pamięci Wątek A Operacja na i Wątek A Wątek B Operacja na i Wątek B czas

Sekcja krytyczne Sekcja krytyczna - w programowaniu współbieżnym fragment kodu programu, w którym korzysta się z zasobu dzielonego, a co za tym idzie w danej chwili może być wykorzystywany przez co najwyżej jeden wątek. i = 0 Współdzielony obszar pamięci Wątek A Operacja na i W. A Operacja na i Wątek A Wątek B Operacja na i W. B Operacja na i czas

Wątki problemy Co jeśli sekcja krytyczna jest niepoprawnie zaimplementowana

Przykład Zmienna statyczna np. licznik Inkrementujemy licznik Czekamy chwilę Tworzymy obiekt wątku 1 Tworzymy obiekt wątku 2 Czekamy aż skończy wątek 1 Uruchamiamy wątki Czekamy aż skończy wątek 2 Jaki wynik?

Przykład Zmienna statyczna np. licznik Inkrementujemy licznik Czekamy chwilę Tworzymy obiekt wątku 1 Tworzymy obiekt wątku 2 Czekamy aż skończy wątek 1 Uruchamiamy wątki Czekamy aż skończy wątek 2 Jaki wynik?

Dlaczego to nie działa Każdy wątek ma swój własny lokalny obszar pamięci, zmienne współdzielone domyślnie przechowywane są w postaci lokalnej kopi osobno dla każdego wątku Zmienna static liczbik Współdzielona między wątkami Lokalna kopia licznik Lokalna kopia licznik Wątek 1 Wątek 2

Volatile Volatile oznacza zmienną we wspólnym współdzielonym obszarze pamięci Zmienna static volatile liczbik Współdzielona między wątkami Wspólna kopia licznik Wspólna kopia licznik Wątek 1 Wątek 2

Volatile Volatile oznacza zmienną we wspólnym współdzielonym obszarze pamięci Czy teraz działa? Zmienna static volatile liczbik Współdzielona między wątkami Wspólna kopia licznik Wspólna kopia licznik Wątek 1 Wątek 2

Volatile Volatile oznacza zmienną we wspólnym współdzielonym obszarze pamięci Czy teraz działa? Zmienna static volatile liczbik Współdzielona między wątkami Wspólna kopia licznik Wspólna kopia licznik Wątek 1 Wątek 2

Problem!!! W1 odczytuje 0 W2 odczytuje 0 Wątek 1 Wątek 2 For ( ) End Pobierz licznik For ( ) Pobierz licznik Dodaj licznik + 1 Dodaj licznik + 1 Zapisz licznik Tak być powinno End Zapisz licznik licznik = 0 For ( ) Wątek 1 Wątek 2 End Pobierz licznik Dodaj licznik + 1 Tak może być For ( ) Pobierz licznik Zapisz licznik Dodaj licznik + 1 End W1 i 0+1 = 1 W2 i 0+1 = 1 Zapisz licznik W1 zapisuje 1 W2 zapisuje 1 Powinno być 2

Zmienne Atomic Zmienne typu ATOMIC to proste zmienne gwarantujące poprawną współbieżność Klasa AtomicBoolean AtomicInteger AtomicLong AtomicReference ( )

Volatile Jak używać Volatile aby było dobrze: Dla wielodostępu używać tylko do operacji atomowych Np. przypisanie / odczyt Voletile informuje JVM że operacje mają być prowadzone na współdzielonej pamięci JVM utrzymuje oryginalną kolejność operacji na zmiennej volatile (normalnie w wyniku optymalizacja kolejność operacji często jest zmieniana tak aby np..zminimalizować ilość wymiany danych pomiędzy rejestrami a pamięcią)

Bezpieczeństwo wątków zamki/monitory Zakładanie zamków na obiekcie: Wykorzystanie metody typu synchronized Wykorzystanie bloku typu sychronized np.: private double stankonta; public synchronized void wplata(double ile){ stankonta += ile; } public synchronized void wyplata(double ile){ stankonta -= ile; } Zasada działania podczas uruchomienia metody synchronized następuje zatrzaśnięcie blokady (na czas realizacji tej metody) Zakończenie wykonywania metody zwalnia blokadę inne wątki też mogą korzystać z danego obiektu.

Bezpieczeństwo wątków - zamki Sekcja krytyczna

Bezpieczeństwo wątków - zamki Sekcja krytyczna Każdy obiekt ma wewnętrzną zmienną typu boolean określającą zamek. Wywołanie synchronized zatrzaskuje zamek Gdy zamek jest zatrzaśnięty inne wątki nie mają dostępu do zmiennej przechodzą w stan wait Wyjście z metody synchronized zwalnia zamek Inni mogą wejść

Jak działa synchronized Algorytm Petersona dla 2 wątków Obydwa wątki uruchamiane są równolegle procedure processone; begin while true do begin {część prgramu przed sekcją krytyczną} flag[1]:=true; turn:=2; repeat whose:=turn; other:=flag[2]; until (whose=1 or not other) {sekcja krytyczna} flag[1]:=false; {pozostała część programu} end; end; procedure processtwo; begin while true do begin {część prgramu przed sekcją krytyczną} flag[2]:=true; turn:=1; repeat whose:=turn; other:=flag[1]; until (whose=1 or not other) {sekcja krytyczna} flag[2]:=false; {pozostała część programu} end; end; Źródło: http://www.algorytm.org/wzajemne-wykluczanie/algorytm-petersona-dla-2-procesow.html

Opis problemu: Wątki przykład Producent - Konsument Typowy przykład programowania współbieżnego Producent produkuje towar, po jego wyprodukowaniu umieszcza go w magazynie Jeśli produkt jest w magazynie, producent nie może do niego włożyć nowego towaru. Może włożyć dopiero jak konsument opróżni magazyn Konsument czeka, aż pojawi się towar w magazynie Gdy jest towar w magazynie konsument pobiera go i czeka na nowy towar Interpretacja przesyłanie komunikatów między dwoma wątkami

Wątki przykład Producent - Konsument Wait zwalnia zatrzask związany z synchronized Wait zwalnia zatrzask związany z synchronized

Wątki przykład Producent - Konsument Wait zwalnia zatrzask związany z synchronized

Wątki przykład Producent - Konsument

Wątki przykład Producent - Konsument Wait zwalnia zatrzask związany z synchronized Wait zwalnia zatrzask związany z synchronized

Semafory Ograniczenia synchronized Działają jedynie gdy jeden wątek ma dostęp do sekcji krytycznej, czasem chcemy by jednocześnie kilka wątków miało dostęp do danego zasobu, wówczas synchronized nie pomoże Rozwiązanie: Semaphore Semafor pozwala na wejście do sekcji krytycznej określonej liczbie wątków: Wejście i wyjście odbywa się na zasadzie uzyskiwania permitów liczba możliwych permitów jest ograniczona przez użytkownika w konstruktorze.

Klasa Semaphore Konstruktor definiujemy liczbę permitów i/lub czy semafor ma być fair. Bycie fair oznacza, że dany wątki które wystąpiły jako pierwsze po dostęp dostaną go jako pierwsze. Jeśli opcja nie zaznaczona to bycie nie fair Oznacza, że dostęp do zasobu jest losowy Pobranie jednego lub określonej liczby permitów. Jeśli permit niedostępny to acquire blokuje wątek aż permit będzie dostepny Zwraca liczbę int opisującą ilość dostępnych permitów Zwolnienie permitu/permitów wywoływane na przy wyjściu z sekcji krytycznej i powoduje oddanie do semafora permitów

Semaphore

Semaphore przykładowa implementacja

Przerywanie wątków Wątków nie należy przerywać przez wywołanie stop!!! Wątki przerywamy przez wywołanie polecenia interrupt() Polecenie interrupt() doprowadza do wystąpienia wyjątku w metodach uśpionych (sleep, wait) Nie da się normalnie przerwać wątku realizującego proces obliczeniowy

Przerywanie wątku

Przerywanie wątku

Przerywanie wątku

Przerywanie wątku

Przerywanie wątku Dlaczego wyjątek? Problem gdy w wątku otwarte zasoby Gdyby to przerywanie było niekontrolowane to problem ze zwalnianiem zasobu Wyjątek pozwala też na kontrolowane zamkniecie wątku Wyjątek pozwala na posprzątanie

Bezpieczeństwo wątków zamki/monitory Słowo synchronized użyte przy deklaracji funkcji zakłada zamek na obiekcie this Synchronized można użyć jako instrukcji języka np: Zamek zamykamy zawsze na jak najkrótszym kawałku kodu

Bezpieczeństwo wątków zamki/monitory

Bezpieczeństwo wątków zamki/monitory

Problem Wspólna synchronizacja wielu wątków implementowanych w różnych klasach Zamek można zakładać na dowolnym obiekcie nie koniecznie this np.

Problem ucztujących filozofów Przy wspólnym stole zasiadło pięciu chińskich filozofów. Filozofowie z zamiłowaniem oddają się czynności myślenia, jednakże muszą się co jakiś czas posilać. Na stole, przy którym siedzą, znajduje się pięć talerzy (po jednym dla każdego), jeden półmisek z ryżem (wspólny dla wszystkich, do którego dostęp jest nieograniczony) oraz pięć pałeczek, niezbędnych do jedzenia ryżu, które zostały ułożone na przemian z talerzami, tak że każdy filozof może mieć dostęp do dwóch pałeczek, po prawej oraz po lewej stronie talerza, przy czym każdą pałeczkę współdzieli z sąsiadem. Zdefiniuj wątek Filozof, zapewniając następujące warunki: a. Każdy filozof może myśleć do woli, niezależnie od pozostałych. b. Filozof może zacząć jeść tylko jeśli udało mu się podnieść dwie pałeczki. c. Pałeczka nie może być podniesiona przez dwóch filozofów w tym samym czasie. d. Pałeczki podnoszone są pojedynczo. e. Program powinien działać zarówno w przypadku ostrej rywalizacji o jedzenie, jak i w przypadku braku rywalizacji. f. Nie może dochodzić do zakleszczeń (zarówno w wersji deadlock jak i livelock) ani do zagłodzenia (w tym przypadku rozumianego dosłownie). Źródło: materiały dydaktyczne do szkolenia Komputery Dużej Mocy UMCS 2012

Rozwiązanie 1

Rozwiązanie 1 Może dojść do zagłodzenia filozofów

Rozwiązanie 1 Rozwiązanie: umożliwić podejście do stołu max tylu filozofom aby nie doszło do zagłodzenia, tak aby przynajmniej jeden miał szansę podnieść 2 pałeczki Co jeśli na raz każdy podniesie jedną pałeczkę?

Rozwiązanie 2 Pozwalamy wejść tylu filozofom aby zawsze jeden na pewno mógł podjąć parę pałeczek Jak obydwie pałeczki oddane to zwalniamy miejsce przy stole

Problem ucztujących filozofów Jaki scenariusz problem opisuje Gdy mamy konkurencyjny dostęp do kilku zasobów naraz Konieczność zarządzania wspólnym dostępem do zasobów Unikanie deadlocków poprzez zagwarantowanie aby przynajmniej jeden zasób miał szansę na kompletny dostęp do wszystkich wymaganych zasobów

Problem czytelników i pisarzy Klasyczny problem programowania wielowątkowego: Mamy jeden zasób dzielony wśród użytkowników odpowiednio czytelników i pisarzy Z zasobu może korzystać na raz wielu czytelników Z zasobu może korzystać na raz jeden pisarz gdy pisarz pisze do zasobu nikt nie może czytać,

Potrzebny arbiter Arbiter zarządza kto ma dostęp do zasobu Czy czytelnicy Czy pisarze Jakie są priorytety czytelników/pisarzy

Czytelnicy i pisarze

Czytelnik

Pisarz

Czytelnia

Czytelnia Może dojść do zagłodzenia pisarza, bo może się zdarzyć tak, że zawsze będzie jakiś czytelnik

Czytelnia v2 Zbieramy info o tym że pisarz czeka w kolejce Jeśli pisarz czeka to odstępujemy mu miejsca Jak pisarz się doczekał to zwalniamy czas

Czytelnia v2 Jeśli pisarz czeka to odstępujemy mu miejsca Zbieramy info o tym że pisarz czeka w kolejce Może dojść do zagłodzenia czytelników gdyby było więcej pisarzy, bo oni zawsze mają pierwszeństwo. Jak pisarz się doczekał to zwalniamy czas

Czytelnia v3

Czytelnia v3 Zbieramy informację o tym że pisarz skończył pisać Jeżeli pisarz czeka to mimo wszystko oddajemy czas czytelnikom aby zdążyli to przeczytać Na koniec pisania ustawiamy info że pisarz coś napisał Resetujemy gdy przynajmniej jeden czytelnik wszedł

Java Collections a wątkobezpieczność Dwie struktury są wątko-bezpieczne: Vector - odpowiednik listy Hashtable odpowiednik HashMap Wątkobezpieczność można osiągnąć przez Collections.synchronizedXXX(collection) Poprzez wykorzystanie struktur z pakietu java.util.concurrent

Inne elementy Java Collections Fabryka: Collections.synchronizedXXX(collection) Gdzie XXX to: Collection, List, Map, Set, SortedMap oraz SortedSet Pozwala na tworzenie wątko-bezpiecznych kolekcji Uwaga 1!!! wątko-bezpieczne operacje to: dodawanie, usuwanie, itp.. Uwaga 2!!! Iteratory nie są bezpieczne

Inne elementy Java Collections + iteratory Scenariusz:

Inne elementy Java Collections + iteratory Scenariusz: Wyjątek: java.util.concurrentmodificationex ception Bo w trakcie działania wątku obsługującego iterator dodajemy nowy element i iterator nie może zostać zmodyfikowany!!!!!

Inne elementy Java Collections + iteratory Rozwiązanie: Operacje na iteratorach stanowią sekcję krytyczną Uwaga: Jak iterujemy to inne wątki są blokowane!!!! Bardzo niekorzystne

Inne elementy Java Collections Concurrent java.util.concurrent cz.1 Copy on write collection dane przechowywane są w niemodyfikowalnej tablicy. Dodanie nowego elementu powoduje stworzenie nowej tablicy dobra gdy ważniejszy jest odczyt niż zapis danych do kolekcji Przykłady: CopyOnWriteArrayList, CopyOnWriteArraySet.

Inne elementy Java Collections Concurrent java.util.concurrent cz.2 Compare-And-Swap (CAS) collection modyfikacja wartości odbywa się poprzez zrobienie lokalnej kopii wartości i wówczas przeprowadzana jest operacja. Gdy na koniec uzyskujemy wynik operacji, wartość jest porównywana z wartością początkową. Gdy obie są takie same to zapisujemy wynik, gdy nie to powtarzamy obliczenia jeszcze raz. Przykłady: ConcurrentLinkedQueue, ConcurrentSkipListMap.

Inne elementy Java Collections Concurrent java.util.concurrent cz.3 Wykorzystanie semaforów (java.util.concurrent.lock.lock) W odróżnieniu od synchronized, Lock zwykle zakładane są na fragmencie kolekcji, więc blokują jedynie jej fragment a nie całość. Przykłady większość kolejek implementujących BlockingQueue ConcurrentHashMap - ConcurrentMap (interfejs)

Egzekutory Java oferuje egzekutory: interface Executor{ void execute(runable task) } pozwala na elastyczne zarządzanie wątkami.

Egzekutory Java oferuje dla Egzekutorów również: ExecutorService Interface Rozszerza Executor i pozwala na zarządzanie zadaniami jak również zwraca Feature obiekty do śledzenia progresu w wykonywaniu asynchronicznych zadań. Collable<T> - alternatywa dla Runnable pozwala na zwracanie wyniku z metody run. Metody: get() zwraca wynik i czeka na zakończenie zadania cancel() skasowanie zadania isdone() czy zadanie zakończone iscancelled() czy zadanie skasowane

ExecutorService Przykład ThreadPoolExecutor( int corepoolsize, //Bazowa liczba watków int maximumpoolsize, //Maksymalna liczba wątków long keepalivetime, //Czas utrzymania wątków TimeUnit unit, //jednostka czasu dla keepalive BlockingQueue<Runnable> workqueue //Kolejka zadań )

ExecutorService przykładowe implementacje Klasa Executors zawiera przykładowe implementacje ThreadPoolExecutor: newsinglethreadexecutor(threadfactory threadfactory) tworzy jeden wątek roboczy do wykonywania zadań zgodnego z kolejkom newcachedthreadpool() tworzy nowe wątki o ile sa konieczne, jeśli nie to używa starych newfixedthreadpool(int nthreads) pula wątków o stałym rozmiarze newscheduledthreadpool(int corepoolsize) pozwala na zarządzaniem kolejnoscią wykonania np. wykonanie okresowe zadań

Przykład Calleble będzie zwracał String Calleble zwraca String Zapamietujemy Feature Tworzymy egzekutor na 10 wątków Dodajemy zadania do wykonania Odczytujemy wyniki w sposób asynchroniczny Przeglądając które zadanie się skończyło Wyłączamy egzekutor

Przykład 2 (bardziej elegancki) Calleble będzie zwracał String Calleble zwraca String Tworzymy CompletionService Tworzymy egzekutor na 10 wątków Dodajemy zadania do wykonania Wyłączamy egzekutor Polecenie take() w sposób blokujący czeka aż pojawi się jakiś wynik.

DeadLocks Występuje gdy blokady składane sa w niewłaściwej kolejności Wątek 1 blokuje A, czeka na B Wątek 2 blokuje B, czeka na A

DeadLocks Scenariusz: System wielowątkowy który z obiektów buduje drzewo. Może dojść do sytuacji w której: Wątek A dodaje dziecko B Wątek B dodaje obiekt rodzica A A Wywołuje metodę addchild(b) B Wywołuje metodę addparent(a)

A B Żródło: http://tutorials.jenkov.com/java-concurrency/deadlock.html

DeadLocks Występuje gdy blokady składane sa w niewłaściwej kolejności Wątek 1 blokuje A, czeka na B Wątek 2 blokuje B, czeka na A Rozwiązanie: Zakładanie blokad zawsze w tej samej kolejności np. najpierw zakładamy zawsze na rodzicu potem na dziecku modyfikacja kolejności zakładania blokad setparent oraz setparentonly

NestedLock Występuje gdy mamy zagnieżdżone monitory Wywołanie wait() na jednym nie zwalnia blokady na drugim monitorze Wątek 1 Wątek 2

blokada na A, blokada na B Wait() na B (odblokowanie B) Ale A pozostaje ciągle zablokowane Drugi wątek nigdy nie osiągnie polecenia notify(), gdyż jest zablokowany na this Żródło: http://tutorials.jenkov.com/java-concurrency/nested-monitor-lockout.html

NestedLock Występuje gdy mamy zagnieżdżone monitory Wywołanie wait() na jednym nie zwalnia blokady na drugim monitorze Rozwiązanie: Unikanie zagnieżdżonych monitorów