Podstawy współbieżności

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

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

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

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

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

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

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

Język Java wątki (streszczenie)

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

Kurs programowania. Wykład 8. Wojciech Macyna

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

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

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

Wątki w Javie. Piotr Tokarski

Język Java wątki (streszczenie)

Programowanie komputerów

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

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

Współbieżność w Javie

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

Współbieżność w Javie

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

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

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

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

Programowanie współbieżne i rozproszone

Programowanie wielowątkowe. Tomasz Borzyszkowski

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

Java. Programowanie Obiektowe Mateusz Cicheński

Wykład 5. Synchronizacja (część II) Wojciech Kwedlo, Wykład z Systemów Operacyjnych -1- Wydział Informatyki PB

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

Programowanie współbieżne Laboratorium nr 11

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

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

Programowanie wielowątkowe: podstawowe koncepcje, narzędzia w Javie. J. Starzyński, JiMP2, rok akad. 2005/2006

Systemy Rozproszone - Ćwiczenie 4

Aplikacja wielowątkowa prosty komunikator

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

Przetwarzanie równoległe i współbieżne

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

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Dokumentacja do API Javy.

JAVA W SUPER EXPRESOWEJ PIGUŁCE

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

Systemy operacyjne. Zajęcia 11. Monitory

Multimedia JAVA. Historia

Monitory. Jarosław Kuchta

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

1 Atrybuty i metody klasowe

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Wątki (Threads) Potrzeby. Przetwarzanie równoległe i współbieŝne. Cechy programowania wątkowego. Concurrent programming is like

Aplikacje RMI

Java: interfejsy i klasy wewnętrzne

Programowanie współbieżne Laboratorium nr 12

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

Java SE, Laboratorium nr 8 Wątki

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

1. Co można powiedzieć o poniższym kodzie? public interface I { void m1() {}; static public void m2() {}; void abstract m3();

W Javie wątki są obiektami zdefiniowanymi za pomocą specjalnego rodzaju klas.

Algorytmy z powrotami. Algorytm minimax

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Zaawansowany kurs języka Python

1. Co można powiedzieć o poniższym kodzie (zakładając, że zaimportowano wszystkie niezbędne klasy)?

Programowanie obiektowe zastosowanie języka Java SE

Języki i metody programowania Java INF302W Wykład 2 (część 1)

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

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Programowanie obiektowe

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

Zaawansowane programowanie w C++ (PCP)

Wywoływanie metod zdalnych

1. Co można powiedzieć o poniższym kodzie?

Polimorfizm, metody wirtualne i klasy abstrakcyjne

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

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

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Generatory. Michał R. Przybyłek

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

7 Pewne uzupełnienia Przepływ sterowania Układacze... 6

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

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

Laboratorium z przedmiotu: Inżynieria Oprogramowania INEK Instrukcja 6

Enkapsulacja, dziedziczenie, polimorfizm

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

Wykład 4: Klasy i Metody

Języki i metody programowania Java. Wykład 2 (część 2)

Programowanie w Javie 1 Wykład i Ćwiczenia 3 Programowanie obiektowe w Javie cd. Płock, 16 października 2013 r.

Wykład 6: Dziedziczenie

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Aplikacje RMI Lab4

Laboratorium z przedmiotu: Inżynieria Oprogramowania INEK Instrukcja 7

4.1 Napisz kod, w którym definiujesz, tworzysz oraz uruchamiasz wątki z uŝyciem klas java.lang.thread oraz java.lang.runnable.

Programowanie obiektowe

Programowanie i projektowanie obiektowe

Dawid Gierszewski Adam Hanasko

Aplikacja wielow tkowa prosty komunikator

Metody Metody, parametry, zwracanie wartości

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Transkrypt:

Podstawy współbieżności Algorytmy i struktury danych. Wykład 6. Rok akademicki: 2010/2011 Od koncepcji współbieżności do systemów rozproszonych Współbieżnośd rozważany na poziomie koncepcyjnym sposób realizacji zadao obliczeniowych dopuszczający możliwośd jednoczesnego wykonywania więcej niż jednej czynności. Realizacja koncepcji współbieżności: systemy z podziałem czasu (w rzeczywistości zadania nie są realizowane w sposób równoległy; czas pracy procesora dzielony jest pomiędzy realizowane zadania; jest to praca pozornie równoległa) systemy równoległe (pozwalające na rzeczywistą równoległośd): maszyny wieloprocesorowe (komunikacja odbywa się za pośrednictwem pamięci operacyjnej), systemy rozproszone (połączone ze sobą komputery współpracujące ze sobą w celu rozwiązania zadania; komunikacja odbywa się za pośrednictwem sieci komputerowej). 2 1

Zalety współbieżności zwiększenie wydajności (skrócenie czasu realizacji programu): w systemach równoległych jednoczesne wykonywanie wielu zadao (na różnych procesorach/maszynach) w systemach z podziałem czasu lepsze wykorzystanie zasobów komputera 3 Wady współbieżności Zwiększona trudnośd w projektowaniu algorytmów przetwarzania: zaprojektowanie właściwego sposobu podziału zadania na realizowane równolegle podzadania, określenie zasad komunikacji pomiędzy realizowanymi równolegle wątkami, określanie zasad dostępu do współdzielonych danych, zwiększone prawdopodobieostwo popełnienia błędów. 4 2

Realizacja koncepcji współbieżności w języku Java wątki: logicznie wyodrębnione sekwencje instrukcji realizowane w sposób pozornie równoległy; wykorzystują mechanizm podziału czasu; realizowane są w obrębie tej samej maszyny wirtualnej; programowanie rozproszone (sieciowe): komunikujące się ze sobą programy uruchamiane na różnych komputerach (i różnych maszynach wirtualnych); programowanie rozproszone wykorzystuje wielowątkowośd. 5 Program jednowątkowy Wątek - częśd programu, która może byd realizowana w sposób współbieżny. Program jednowątkowy - składa się z jednej sekwencji instrukcji /tzw. wątek główny programu/ (w języku Java tworzą one treśd metody main( ) w klasie bazowej). 6 3

Program wielowątkowy Z poziomu wątku głównego tworzone są inne, realizowane współbieżnie, wątki; Każdy wątek może tworzyd kolejne wątki; Wątki mogą korzystad ze wspólnych danych; Program wielowątkowy kooczy pracę po zrealizowaniu wątku głównego i wszystkich pozostałych wątków. 7 Reprezentacja wątków w języku Java Wątek reprezentowany jest przez klasę będącą potomkiem klasy Thread, której najważniejsze metody to: public Thread() - konstruktor obiektu reprezentującego wątek public Thread(String name) - konstruktor pozwalający nadad nazwę tworzonemu wątkowi public void run() - definiuje operacje realizowane w ramach wątku public void start() - wywołuje metodę run() 8 4

Definiowanie wątków za pomocą obiektów klasy Thread i klas pochodnych class Gwiazdka extends Thread { public void run() { for (int i = 0; i < 10;i++) { System.out.print("*"); try { sleep(1000); catch(interruptedexception e) { 9... class Plus extends Thread { public void run() { for (int i = 0; i < 10;i++) { System.out.print("+"); try { sleep(1000); catch(interruptedexception e) { 10 5

... public class TworzenieWatkow1 { public static void main(string [] args) { Gwiazdka g = new Gwiazdka(); Plus p = new Plus(); g.start(); p.start(); System.out.print("KONIEC"); Wyniki działania programu KONIEC*++**++*+*+*+*+*+**+ Definicja metody sleep (w klasie Thread): public static void sleep(long millis) throws InterruptedException 11 Definiowanie wątku za pomocą klasy implementującej interfejs Runnable Obliczenia realizowane przez wątek opisane są w klasie implementujacej interfejs Runnable Interfejs Runnable definiuje nagłówek jednej metody: public void run() metoda ta definiuje operacje realizowane w ramach wątku. Przedstawiony mechanizm tworzenia wątków należy stosowad wtedy, gdy klasa reprezentująca wątek jest potomkiem klasy innej niż Thread (np. klasy Applet) i - z uwagi na jednokrotny charakter dziedziczenia w języku Java - nie może dziedziczyd cech klasy Thread. Obiekt klasy implementującej interfejs Runnable należy przekazad jako parametr konstruktora w trakcie tworzenia obiektu typu Thread. Uruchomienie wątku następuje za pomocą metody start(), która wywołuje metodę run(). 12 6

Przykład class Gwiazdka implements Runnable { public void run() { for (int i = 0; i < 10;i++) { System.out.print("*"); try { Thread.sleep(1000); catch(interruptedexception e) { 13... class Plus implements Runnable { public void run() { for (int i = 0; i < 10;i++) { System.out.print("+"); try { Thread.sleep(1000); catch(interruptedexception e) { 14 7

... public class TworzenieWatkow2 { public static void main(string [] args) { Thread g = new Thread(new Gwiazdka()); Thread p = new Thread(new Plus()); g.start(); p.start(); System.out.print("KONIEC"); Wyniki działania programu KONIEC*+*+*+*+*+*+*+*+*+*+ 15 Korzystanie ze wspólnych zasobów Wątki mogą korzystad ze wspólnych zasobów, ale program powinien sterowad dostępem do współużytkowanych obiektów. Do sterowanie dostępem do wspólnych zasobów służy mechanizm synchronizacji. 16 8

Korzystanie ze wspólnych zasobów bez mechanizmu synchronizacji Przykład programu nie zawierającego mechanizmów synchronizacji - wspólnym zasobem jest standardowy strumieo wyjściowy. class Watek1 implements Runnable { public void run() { for (int i = 1; i <= 10; i++) { try { Thread.sleep(100); catch (InterruptedException e) { System.out.print("A"); 17... class Watek2 implements Runnable { public void run() { for (int i = 1; i <= 10; i++) { try { Thread.sleep(100); catch(interruptedexception e) { System.out.print("B"); 18 9

... public class WspolneZasoby { public static void main(string [] args) { Thread w1 = new Thread(new Watek1()); Thread w2 = new Thread(new Watek2()); w1.start(); w2.start(); System.out.println("KONIEC"); Wynik działania programu: KONIEC BABABAABBABABABAABBA 19 Sekcja krytyczna wątku Sekcja krytyczna wątku - fragment programu (będącego częścią wątku), z poziomu którego następuje odwołanie do wspólnego zasobu. W danej chwili tylko jeden wątek może realizowad kod tworzący sekcję krytyczną. 20 10

Schemat sekcji krytycznej Wątek 1 Wątek 2 sekcja krytyczna sekcja krytyczna Wspólny zasób 21 Realizacja sekcji krytycznej Jeżeli wątek A realizuje swoją sekcję krytyczną, to wątek B, po dojściu do fragmentu kodu tworzącego jego sekcję krytyczną, zostanie wstrzymany, aż do chwili zakooczenia realizacji sekcji krytycznej przez wątek A. Po zakooczeniu realizacji sekcji krytycznej wątku A realizacja wątku B zostanie wznowiona. 22 11

Monitor jako narzędzie realizacji sekcji krytycznej mechanizm pozwalający na blokowania dostępu do obiektu; blokowanie odbywa się poprzez zajęcie monitora obiektu; monitor może zastad zajęty tylko przez jeden wątek; jeśli wątek A chce zająd monitor obiektu, który jest aktualnie w posiadaniu wątku B, to realizacja wątku A jest wstrzymywana do momentu zwolnienia monitora przez wątek B; każdy obiekt występujący w programie posiada oddzielny monitor. Wątek 1 Wątek 2 sekcja krytyczna Monitor Wspólny zasób sekcja krytyczna 23 Monitor w języku Java synchronized (nazwaobiektu) //zajęcie monitora obiektu {... instrukcje tworzące sekcję krytyczną... //zwolnienie monitora obiektu 24 12

Przykład class Watek1 implements Runnable { public void run() { synchronized (System.out) { for (int i = 1; i <= 10; i++) { try { Thread.sleep(100); catch (InterruptedException e) { System.out.print("A"); 25... class Watek2 implements Runnable { public void run() { synchronized (System.out) { for (int i = 1; i <= 10; i++) { try { Thread.sleep(100); catch(interruptedexception e) { System.out.print("B"); 26 13

... public class WspolneZasoby { public static void main(string [] args) { Thread g = new Thread(new Watek1()); Thread p = new Thread(new Watek2()); g.start(); p.start(); System.out.println("KONIEC"); Wyniki działania programu: KONIEC AAAAAAAAAABBBBBBBBBB UWAGA: Program nie określa, który wątek zajmie monitor obiektu System.out jako pierwszy. Z tego powodu przy kolejnej realizacji programu można uzyskad wynik: KONIEC BBBBBBBBBBAAAAAAAAAA 27 Metoda wait synchronized (obiekt) {... obiekt.wait()... musi byd wywoływana z sekcji krytycznej wątku (gdy wątek zajął monitor obiektu obiekt), powoduje, że realizacja wątku jest zawieszana i wątek zwalnia monitor (który może zostad zajęty przez inny wątek), realizacja zawieszonego wątku może zostad wznowiona wówczas, gdy inny wątek zajmie monitor obiektu obiekt i uruchomi metodę notify() lub notifyall(). 28 14

Metoda notify synchronized (obiekt) {... obiekt.notify()... wznawia działanie jednego (wybranego przypadkowo) wątku wstrzymanego wcześniej za pomocą metody obiekt.wait(). Realizacja wznowionego wątku może rozpocząd się po zakooczeniu realizacji sekcji krytycznej bieżącego wątku 29 Metoda notifyall synchronized (obiekt) {... obiekt.notifyall()... wznawia działanie wszystkich wątków wstrzymanych wcześniej za pomocą metody obiekt.wait(). Realizacja jednego z nich rozpocznie się po zakooczeniu realizacji sekcji krytycznej bieżącego wątku. 30 15

Problem producenta i konsumenta Producent Konsument Pojemnik 31 P-K, wersja I class Pojemnik { private int liczba; synchronized public int pobierz() { System.out.println("Z pojemnika pobierana jest wartosc: " + liczba); return liczba; synchronized public void wstaw(int liczba) { System.out.println("Do pojemnika wstawiana jest wartosc: " + liczba); this.liczba = liczba; 32 16

P-K, wersja I, ciąg dalszy class Producent implements Runnable { Pojemnik p; Producent(Pojemnik p) { this.p = p; public void run() { for (int i = 1; i <= 10; i++) { try { Thread.sleep((int) (100 * Math.random())); catch (InterruptedException e) { p.wstaw(i); 33 P-K, wersja I, ciąg dalszy class Konsument implements Runnable { Pojemnik p; Konsument(Pojemnik p) { this.p = p; public void run() { for (int i = 1; i <= 10; i++) { try { Thread.sleep((int) (100 * Math.random())); catch (InterruptedException e){ p.pobierz(); 34 17

P-K, wersja I, ciąg dalszy public class ProducentKonsument1 { public static void main(string[] args) { Pojemnik poj = new Pojemnik(); Producent prod = new Producent(poj); Konsument kons = new Konsument(poj); Thread watek1 = new Thread(prod); Thread watek2 = new Thread(kons); watek1.start(); watek2.start(); 35 P-K, wersja I, ciąg dalszy Efekt działania programu: Do pojemnika wstawiana jest wartosc: 1 Z pojemnika pobierana jest wartosc: 1 Do pojemnika wstawiana jest wartosc: 2 Do pojemnika wstawiana jest wartosc: 3 Do pojemnika wstawiana jest wartosc: 4 Z pojemnika pobierana jest wartosc: 4 Do pojemnika wstawiana jest wartosc: 5 Do pojemnika wstawiana jest wartosc: 6 Do pojemnika wstawiana jest wartosc: 7 Do pojemnika wstawiana jest wartosc: 8 Z pojemnika pobierana jest wartosc: 8 Do pojemnika wstawiana jest wartosc: 9 Do pojemnika wstawiana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 36 18

P-K, wersja II class Pojemnik { private int liczba; private boolean czyjestwartoscwpojemniku = false; public int pobierz() { while (!czyjestwartoscwpojemniku) ; //pusta petla System.out.println("Z pojemnika pobierana jest wartosc: " + liczba); czyjestwartoscwpojemniku = false; return liczba; public void wstaw(int liczba) { while (czyjestwartoscwpojemniku) ; //pusta petla System.out.println("Do pojemnika wstawiana jest wartosc: " + liczba); this.liczba = liczba; czyjestwartoscwpojemniku = true; 37 P-K, wersja II, ciąg dalszy Efekt działania programu: Do pojemnika wstawiana jest wartosc: 1 Z pojemnika pobierana jest wartosc: 1 Do pojemnika wstawiana jest wartosc: 2 Z pojemnika pobierana jest wartosc: 2 Do pojemnika wstawiana jest wartosc: 3 Z pojemnika pobierana jest wartosc: 3 Do pojemnika wstawiana jest wartosc: 4 Z pojemnika pobierana jest wartosc: 4 Do pojemnika wstawiana jest wartosc: 5 Z pojemnika pobierana jest wartosc: 5 Do pojemnika wstawiana jest wartosc: 6 Z pojemnika pobierana jest wartosc: 6 Do pojemnika wstawiana jest wartosc: 7 Z pojemnika pobierana jest wartosc: 7 Do pojemnika wstawiana jest wartosc: 8 Z pojemnika pobierana jest wartosc: 8 Do pojemnika wstawiana jest wartosc: 9 Z pojemnika pobierana jest wartosc: 9 Do pojemnika wstawiana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 38 19

P-K, wersja III class Pojemnik { private int liczba; private boolean czyjestwartoscwpojemniku = false; synchronized public int pobierz() { if (!czyjestwartoscwpojemniku) try { wait(); catch (InterruptedException e) { System.out.println("Z pojemnika pobierana jest wartosc: " + liczba); czyjestwartoscwpojemniku = false; notify(); return liczba; 39 P-K, wersja III, ciąg dalszy synchronized public void wstaw(int liczba) { if (czyjestwartoscwpojemniku) try { wait(); catch (InterruptedException e) { System.out.println("Do pojemnika wstawiana jest wartosc: + liczba); czyjestwartoscwpojemniku = true; this.liczba = liczba; notify(); 40 20

P-K, wersja III, ciąg dalszy Efekt działania programu: Do pojemnika wstawiana jest wartosc: 1 Z pojemnika pobierana jest wartosc: 1 Do pojemnika wstawiana jest wartosc: 2 Z pojemnika pobierana jest wartosc: 2 Do pojemnika wstawiana jest wartosc: 3 Z pojemnika pobierana jest wartosc: 3 Do pojemnika wstawiana jest wartosc: 4 Z pojemnika pobierana jest wartosc: 4 Do pojemnika wstawiana jest wartosc: 5 Z pojemnika pobierana jest wartosc: 5 Do pojemnika wstawiana jest wartosc: 6 Z pojemnika pobierana jest wartosc: 6 Do pojemnika wstawiana jest wartosc: 7 Z pojemnika pobierana jest wartosc: 7 Do pojemnika wstawiana jest wartosc: 8 Z pojemnika pobierana jest wartosc: 8 Do pojemnika wstawiana jest wartosc: 9 Z pojemnika pobierana jest wartosc: 9 Do pojemnika wstawiana jest wartosc: 10 Z pojemnika pobierana jest wartosc: 10 41 Zjawisko blokady (deadlock) Blokada - sytuacja w której: wątek A: zajął monitor obiektu I, i nie zwalniając go chce zająd monitor obiektu II, wątek B: zajął monitor obiektu II, i nie zwalniając go chce zając monitor obiektu I. Powstanie blokady jest bardzo trudnym do wykrycia błędem logicznym. Języki programowania nie posiadają mechanizmów zapobiegających powstawaniu i/lub usuwaniu blokad - jedynym sposobem ich uniknięcia jest prawidłowe zaprojektowanie algorytmu przetwarzania danych. 42 21

Przykład blokady (1) class Obiekt { void metodapierwsza() { System.out.println("START - metodapierwsza * + Thread.currentThread().getName() + "]"); try { Thread.sleep(10); catch (InterruptedException e) { System.out.println("STOP - metodapierwsza [" + Thread.currentThread().getName() + "]"); 43 Przykład blokady (2) void metodadruga() { System.out.println("START - metodadruga [" + Thread.currentThread().getName() + "]"); try { Thread.sleep(10); catch (InterruptedException e) { System.out.println("STOP - metodadruga [" + Thread.currentThread().getName() + "]"); 44 22

Przykład blokady (3) class Watek1 extends Thread { Obiekt o1; Obiekt o2; Watek1(Obiekt o1,obiekt o2,string nazwa) { super(nazwa); this.o1 = o1; this.o2 = o2; 45 Przykład blokady (4) public void run() { synchronized(o1) { o1.metodapierwsza(); synchronized (o2) { o2.metodadruga(); 46 23

Przykład blokady (5) class Watek2 extends Thread { Obiekt o1; Obiekt o2; Watek2(Obiekt o1,obiekt o2, String nazwa) { super(nazwa); this.o1 = o1; this.o2 = o2; 47 Przykład blokady (6) public void run() { synchronized (o2) { o2.metodapierwsza(); synchronized (o1) { o1.metodadruga(); 48 24

Przykład blokady (7) public class Blokada1 { public static void main(string [] args) { Obiekt obiekt1 = new Obiekt(); Obiekt obiekt2 = new Obiekt(); Thread watek1 = new Watek1(obiekt1, obiekt2,"w1"); Thread watek2 = new Watek2(obiekt1, obiekt2,"w2"); watek1.start(); watek2.start(); 49 Przykład blokady (8) Efekt działania programu: START - metodapierwsza [w1] START - metodapierwsza [w2] STOP - metodapierwsza [w1] STOP - metodapierwsza [w2] 50 25

Zjawisko zagłodzenia wątku (starvation) Zagłodzenie - sytuacja, w której oczekujący wątek nie zostaje dopuszczony przez inne wątki do realizacji zdefiniowanego w nim kodu programu. 51 Przykład zagłodzenia wątku(1) class Liczniki { int pole1 = 0; int pole2 = 0; void zwiekszpole1() { pole1++; void zwiekszpole2() { pole2++; synchronized void wyswietlpola() { System.out.println("Pole1 = " + pole1); System.out.println("Pole2 = " + pole2); 52 26

Przykład zagłodzenia wątku(2) class Watek1 extends Thread { Liczniki licz; Watek1(Liczniki licz) { this.licz = licz; public void run() { for (int i = 0; i < 1000; i++) { synchronized(licz) { licz.zwiekszpole1(); licz.wyswietlpola(); 53 Przykład zagłodzenia wątku(3) class Watek2 extends Thread { Liczniki licz; Watek2(Liczniki licz) { this.licz = licz; public void run() { for (int i = 0; i < 1000; i++) { synchronized(licz) { licz.zwiekszpole2(); licz.wyswietlpola(); 54 27

Przykład zagłodzenia wątku(4) public class Zaglodzenie1 { public static void main(string [] args) { Liczniki licz = new Liczniki(); Thread watek1 = new Watek1(licz); Thread watek2 = new Watek2(licz); watek1.start(); watek2.start(); 55 Przykład zagłodzenia wątku(5) Efekt działania programu: Pole1 = 1000 Pole2 = 0 Pole1 = 1000 Pole2 = 1000 W powyższym przykładzie w trakcie realizacji wątku pierwszego czas pomiędzy zwolnieniem monitora obiektu licz, a jego ponownym zajęciem (w kolejnym obiegu pętli) jest zbyt krótki, aby drugi wątek zdołał zająd wspomniany monitor. 56 28

Przeciwdziałanie zagłodzeniu (1) Mechanizmem nie dopuszczającym do zagłodzenia wątku jest metoda yield zdefiniowana w klasie Thread: public static void yield() jej wywołanie powoduje chwilowe zawieszenie realizacji bieżącego wątku i przydzielenie czasu działania procesora następnemu wątkowi. Stosowanie tej metody gwarantuje, że nie dojdzie do zagłodzenia wątku. 57 Przeciwdziałanie zagłodzeniu (2) class Watek1 extends Thread { Liczniki licz; Watek1(Liczniki licz) { this.licz = licz; public void run() { for (int i = 0; i < 1000; i++) { synchronized(licz) { licz.zwiekszpole1(); if (i % 100 == 0) Thread.yield(); licz.wyswietlpola(); 58 29

Przeciwdziałanie zagłodzeniu (3) class Watek2 extends Thread { Liczniki licz; Watek2(Liczniki licz) { this.licz = licz; public void run() { for (int i = 0; i < 1000; i++) { synchronized(licz) { licz.zwiekszpole2(); if (i % 100 == 0) Thread.yield(); licz.wyswietlpola(); 59 Przeciwdziałanie zagłodzeniu (4) Efekt działania programu: Pole1 = 1000 Pole2 = 901 Pole1 = 1000 Pole2 = 1000 60 30

Semafor w programowaniu Semafor narzędzie synchronizacji, sterujący dostępem do wspólnego zasobu, posiada licznik określający możliwą do wykorzystania liczbę jednostek deficytowego zasobu. 61 Operacje wykonywane na semaforze operacja P P prolaag (holenderski) = probeer te verlagen oznacza próbuj i zmniejsz Operacja wykonywana w chwili, gdy wątek chce zająd pewną liczbę jednostek zasobu Jeśli licznik semafora (liczba wolnych jednostek zasobu) jest większy lub równy od liczby potrzebnych jednostek, to następuje zmniejszenie licznika o liczbę wymaganych przez wątek jednostek. Jeśli wartośd licznika jest mniejsza od liczby potrzebnych jednostek, to wątek zostaje wstrzymany aż do momentu, gdy wartośd licznika odpowiednio wzrośnie. 62 31

Operacje wykonywane na semaforze operacja V V verhoog (holenderski) oznacza zwiększ Operacja wykonywana w chwili, gdy wątek chce zwolnid pewną liczbę jednostek zasobu Następuje zwiększenie wartości licznika o liczbę zwalnianych jednostek zasobu. 63 Implementacja (Silberschatz, Galvin, and Gagne, 1999) public class Semaphore { public Semaphore() { value = 0; public Semaphore(int v) { value = v; public synchronized void P() { /* see next slide */ public synchronized void V() { /* see next slide */ private int value; 64 32

Implementacja (Silberschatz, Galvin, and Gagne, 1999) public synchronized void P() { while (value <= 0) { try { wait(); catch (InterruptedException e) { value --; 65 Implementacja (Silberschatz, Galvin, and Gagne, 1999) public synchronized void V() { ++value; notify(); 66 33

Klasyfikacja semaforów semafor zliczający licznik przyjmuje wartości całkowite semafor binarny: licznik przyjmuje tylko jedną z dwóch wartości: 0 (zasób zajęty) lub 1 (zasób wolny) licznik może byd tylko zmieniany o 1, operacja V (zwiększanie licznika semafora) wykonana na semaforze o liczniku równym 1 nie powoduje żadnych zmian. 67 34