Programowanie obiektowe 2

Slides:



Advertisements
Podobne prezentacje
Blok I: PODSTAWY TECHNIKI Lekcja 7: Charakterystyka pojęć: energia, praca, moc, sprawność, wydajność maszyn (1 godz.) 1. Energia mechaniczna 2. Praca 3.
Advertisements

OBOWIĄZKI INFORMACYJNE BENEFICJENTA Zintegrowane Inwestycje Terytorialne Aglomeracji Wałbrzyskiej.
Tworzenie odwołania zewnętrznego (łącza) do zakresu komórek w innym skoroszycie Możliwości efektywnego stosowania odwołań zewnętrznych Odwołania zewnętrzne.
PRAWO HANDLOWE Mateusz Kabut Katedra Prawnych Problemów Administracji i Zarządzania.
PRACA Z APLIKACJAMI SYSTEM PRZEMIESZCZANIA oraz NADZORU WYROBÓW AKCYZOWYCH EMCS PL 1.
Wyszukiwanie informacji w Internecie. Czym jest wyszukiwarka? INTERNET ZASOBY ZAINDEKSOWANE PRZEZ WYSZUKIWARKI Wyszukiwarka to mechanizm, który za pomocą.
 Czasem pracy jest czas, w którym pracownik pozostaje w dyspozycji pracodawcy w zakładzie pracy lub w innym miejscu wyznaczonym do wykonywania pracy.
Poczta elektroniczna – e- mail Gmail zakładanie konta. Wysyłanie wiadomości.
EWALUACJA JAKO ISTOTNY ELEMENT PROJEKTÓW SYSTEMOWYCH Sonia Rzeczkowska.
Model warstwowy OSI Model OSI (Open Systems Interconnection) opisuje sposób przepływu informacji między aplikacjami programowymi w jednej stacji sieciowej.
Matematyka przed egzaminem czyli samouczek dla gimnazjalisty Przygotowała Beata Czerniak FUNKCJE.
Instalacja nienadzorowana windows xp Jakub klafta.
Python. Języki Programistyczne Microcode Machine code Assembly Language (symboliczna reprezentacja machine code) Low-level Programming Language (FORTRAN,
Najczęściej popełniane błędy w przygotowywanych wnioskach o dofinasowanie Regionalny Program Operacyjny Województwa Pomorskiego na lata Gdańsk,
Definiowanie i planowanie zadań typu P 1.  Planowanie zadań typu P  Zadania typu P to zadania unikalne służące zwykle dokonaniu jednorazowej, konkretnej.
1 Definiowanie i planowanie zadań budżetowych typu B.
Jak tworzymy katalog alfabetyczny? Oprac.Regina Lewańska.
, + - = 0,5 CZYTAJ DOKŁADNIE ZADANIA I POLECENIA. IM TRUDNIEJSZE ZADANIE, TYM BARDZIEJ WARTO JE PRZECZYTAĆ KILKA RAZY.
PORADNIK WPROWADZANIA AKCJI. OGÓLNIE: Akcja musi zostać utworzona i opublikowana co najmniej tydzień przed jej rozpoczęciem. W opisie muszą znajdować.
System operacyjny Renata P. System operacyjny - jest to zbiór nadrzędnych i niezbędnych programów umożliwiających pracę na komputerze. Jest on pośrednikiem.
Język Java Paweł Rajba
Dziedziczenie, polimorfizm, Interfejsy
Mikroprocesory.
Test analizy wariancji dla wielu średnich – klasyfikacja pojedyncza
Schematy blokowe.
Wytwarzanie oprogramowania sterowane przypadkami testowymi
Wątki, programowanie współbieżne
DEFINICJA I ZASTOSOWANIE W JĘZYKU HASKELL
SYSTEM KWALIFIKACJI, AWANSÓW I SPADKÓW
Podstawowe polecenia systemu
On-the-Fly Garbage Collection
Prezentacja o Ubuntu Jakub Kociemba 2TI.
Liczby pierwsze.
Akademia C# - Lab2 Zmienne, instrukcje warunkowe, pętle, debugger,
Rekursje Tak jak w innych językach funkcje mogą odwoływać się same do siebie Możemy regulować głębokość przed stwierdzeniem błędu (MaxRecursion, $RecursionLimit,
ALGORYTMY I STRUKTURY DANYCH
Akademia C# lab. 9 Zdarzenia i delegaty.
Programowanie obiektowe Wykład 10
Programowanie obiektowe
Wstęp do Informatyki - Wykład 3
Optymalizacja programów Open-Source
Przewodnik Udoskonalanie listy wyników w wyszukiwarce naukowej
Lekcja 1 – Hello World! Visual Studio, coś łatwego na początek 
Programowanie obiektowe
Materiały pochodzą z Platformy Edukacyjnej Portalu
Materiały pochodzą z Platformy Edukacyjnej Portalu
Kurs języka C++ – wykład 13 ( )
Elementy fizyki kwantowej i budowy materii
Inżynieria Oprogramowania Laboratorium
PROGRAMY DO KONTROLI RODZICIELSKIEJ
Git - system kontroli wersji
Bezpieczeństwo dostępu do danych w systemie Windows
Języki programowania.
PAMIĘĆ I UWAGA. Dlaczego w szkole tak trudno cokolwiek zapamiętać?
Laboratorium 1 – obsługa wejść i wyjść
Koszyk danych.
Podstawy informatyki Zygfryd Głowacz.
ALGORYTMY I STRUKTURY DANYCH
Strukturalne wzorce projektowe
Pisemne dzielenie liczb naturalnych
PGO Kolekcje Michail Mokkas.
Proste obliczenia w arkuszu kalkulacyjnym
Implementacja rekurencji w języku Haskell
Znajdowanie liczb pierwszych w zbiorze
POZNAJEMY PULPIT Opracowanie: mgr Barbara Benisz SP nr 20 w Rybniku
Wyrok WSA w Bydgoszczy z dnia 27 października 2016 r., I SA/Bd 613/16
Modelowanie obiektowe - system zarządzania projektami
Autor: Magdalena Linowiecka
Asynchroniczne operacje I/O za pomocą IOCP
Zapis prezentacji:

Programowanie obiektowe 2 Wątki

Java-wątki Proces – działający program, ma własną przestrzeń adresową Wątki działają w ramach jednego procesu, mają wspólną pamięć. Nawet przy zwykłych programach mamy współbieżność: jeden wątek wykonuje metodę main(),drugi obsługuje zarządzanie pamięcią (GarbageCollection),inny odświeża ekran

Java-wątki Tworzenie wątku – sposób 1: piszemy klasę dziedziczącą po klasie Thread i przesłaniamy jej metodę run,czyli class MójWątek extends Thread { public void run(){ //działanie wątku }

Java-wątki Po czym tworzymy obiekt tej klasy, czyli wątek: MójWątek w = new MójWątek(); (Przykład 1)

Java-wątki Tworzenie wątku – sposób 2: piszemy klasę implementującą interfejs Runnable (z metodą run), tworzymy jej obiekt i przekazujemy go konstruktorowi klasy Thread, czyli:

Java-wątki class MójWątek implements Runnable { public void run(){ //działanie wątku } MójWątek w = new MójWątek(); Thread watek = new Thread(w); (Przykład 2)

Java-wątki Interfejs Runnable jest bardzo prosty: public interface Runnable { public void run(); } Drugi sposób tworzenia wątku jest szczególnie istotny, gdy klasa wątku dziedziczy już z innej klasy; ponieważ nie może dziedziczyć z dwóch klas, musi implementować interfejs Runnable.

Java-wątki Konstruktor klasy Thread jako argument bierze nazwę wątku lub obiekt (typu) Runnable. (Przykład 2,3) Konstruktory klasy Thread: Thread(), Thread(String name), Thread(Runnable target), Thread(Runnable target, String name)

Java-wątki Metoda run w klasie Thread: private Runnable target; public void run(){ if(target!=null) target.run(); } Referencja target ustawiana jest w konstruktorze, jeśli zostanie przekazany parametr klasy implementującej Runnable

Java-wątki Gdy piszemy własną klasę dziedziczącą z Thread, ta postać metody run() jest przesłonięta naszą wersją. Metoda run zawiera główne obliczenie wątku, gdy się skończy, skończy się wątek. Jej uruchomienie (czyli uruchomienie wątku) następuje za pomocą metody start

Java-wątki Gdybyśmy napisali: w.run() metoda run wykonałaby class Test { public static void main(String[] args){ MojWatek w = new MojWatek(); w.start(); } Gdybyśmy napisali: w.run() metoda run wykonałaby się, ale to nie byłby wątek. Metoda start oprócz wywołania run przygotowuje całe środowisko dla działania wątku

Java-wątki Deklaracja metody run jest ustalona w klasie Thread bądź w interfejsie Runnable, więc nie możemy przekazywać jej argumentów. Musi być ona bezargumentowa. Natomiast możemy przekazywać dane do wątku poprzez konstruktor lub pola klasy wątku. Przez pola klasy możemy też pobrać od wątku jakieś dane.

Java-wątki Wątek, nawet gdy się skończył, jako obiekt nadal istnieje, więc mamy dostęp do jego pól. (Przykład 4) Nazwę wątkowi możemy nadać albo w konstruktorze, albo metodą void setName(String n) Metoda String getName() zwraca nazwę wątku (Przykład 5)

Java-wątki Wątek kończy się wraz z zakończeniem działania metody run(). Aby móc kontrolować zakończenie wątku z poziomu innego wątku, najlepiej zrobić to programowo, np. metoda run działając obserwuje wartość jakiegoś pola klasy i w przypadku zmiany tej wartości kończy działanie. (Przykład 6)

Java-wątki W starszych wersjach Javy istniała w klasie Thread metoda stop(),wymuszająca zakończenie wątku. Obecnie się jej nie używa.

Java-wątki W tym samym czasie działać może wiele niezależnych wątków (Przykład 7) Wątki też mogą współdziałać przy wykonywaniu jakiejś pracy (Przykład 8) Mogą korzystać z tych samych obiektów (Przykład 9)

Java-wątki W przykładzie 9 mogą wystąpić błędy. Np. aktualny stan napisu to „abbaaba”. Wątek A wywołuje metodę doklej, chcąc dokleić „a”. Zanim to zrobi, wątek B też wywołuje metodę doklej, chcąc dokleić „b”. Wątek A dokleja „a” i wypisuje „abbaabaa”, wątek B dokleja „b” i wypisuje „abbaabab”.

Java-wątki Rozwiązaniem tej i podobnych sytuacji jest synchronizacja. Tylko jeden wątek w tym samym czasie ma prawo wywołać metodę doklej. Inny przykład tego samego problemu (Przykład 10) Wątki współdzielące te same zasoby mogą powodować niespójność danych.

Java-wątki Testowanie programów wielowątkowych jest trudne, bowiem możemy wiele razy otrzymać wyniki, które wydają się świadczyć o poprawności programu, a przy kolejnym uruchomieniu okaże się, że wynik jest nieprawidłowy. Wyniki uruchamiania programów wielowątkowych mogą być także różne na różnych platformach systemowych.

Java-wątki Synchronizacja jest mechanizmem, który zapewnia, że kilka wykonujących się wątków nie będzie równocześnie działać na tym samym obiekcie (czy pamięci wspólnej) nie będzie równocześnie wykonywać tego samego kodu.

Java-wątki Kod, który może być wykonywany w danym momencie tylko przez jeden wątek , nazywa się sekcją krytyczną. W Javie sekcje krytyczne wprowadza się jako bloki lub metody synchronizowalne.

Java-wątki Blokowanie obiektów jest sterowane słowem kluczowym synchronized.

Java-wątki Synchronizacja w Javie może być wykonana na poziomie metod – słowo kluczowe synchronized występuje przy definiowaniu metody: public synchronized int balance() { … } (Przykład 11)

Java-wątki b) na poziome instrukcji: słowo kluczowe synchronized występuje przy definiowaniu bloku instrukcji (Przykład 12)

Java-wątki Kiedy wątek wywołuje metodę synchronizowaną, zamykany jest monitor (obiekt jest zajmowany przez wątek). Inne wątki usiłujące wywołać na rzecz tego obiektu metodę synchronizowaną (niekoniecznie tą samą) lub usiłujące wywołać instrukcję synchronized z podaną referencją do zajętego obiektu są blokowane i czekają na zakończenie wykonywania metody lub instrukcji synchronized przez wątek który zajął obiekt (zamknął monitor).

Java-wątki Dowolne zakończenie wykonywania metody synchronizowanej lub instrukcji synchronized zwalnia monitor dając czekającym wątkom możliwość dostępu do obiektu.

Java-wątki Wątki działają asynchronicznie. (Przykład 13, 13a) Do koordynacji ich działania służą metody wait(), notify(), notifyAll() wait() zawiesza działanie wątku, aż inny nie wywoła notify() lub notifyAll() wait() można wywołać tylko będąc w metodzie bądź sekcji synchronized. Wykonanie wait() spowoduje zwolnienie monitora. (Przykład 14)

Java-wątki Dlaczego przykład 14 niepoprawny, chociaż metody są synchronized? (Przykład 15) Wymienione metody są metodami klasy Object, więc wątki mogą je wywoływać w dowolnych obiektach. notify() powoduje odblokowanie jednego z wątków, które wywołały wait()

Java-wątki Nie wiadomo, który wątek zostanie odblokowany. Wiadomo że jeden. notifyAll() odblokuje wszystkie

Java-wątki Obie te metody mogą być wywoływane tylko przez wątki zajmujące monitor. Odblokowany przez notify() wątek nie będzie wykonywany natychmiast – musi poczekać na wątek, który go zwolnił, aż ten opuści monitor. Po zwolnieniu monitora odblokowany wątek będzie konkurował z innymi (niezablokowanymi) o przydział do monitora.

Java-wątki Podobne uwagi dotyczą do notifyAll() Problem producenta-konsumenta – przykład koordynacji wątków. Mamy dwie kategorie wątków: producenci i konsumenci. Wątki korzystają ze wspólnego bufora, w danej chwili tylko jeden może z niego korzystać. Producenci wkładają do bufora liczby, gdy jest on pusty. Gdy bufor jest pełny producenci muszą czekać na opróżnienie bufora przez konsumenta.

Java-wątki Konsumenci pobierają liczbę. Jeśli bufor jest już pusty, konsumenci muszą czekać, aż jakiś producent go napełni. (Przykład 16a, 16b)

Java-wątki Opisane wcześniej metody synchronizacji (synchronized, wait, notify itd.) są niskopoziomowe i trudne w użyciu, należy ich unikać. Wiele problemów synchronizacyjnych może być wyrażonych za pomocą kolejek blokujących. problem producenta-konsumenta jest tu dobrym przykładem.

Java-wątki Kolejka blokująca powoduje zablokowanie wątku podczas próby dodania elementu, jeśli jest pełna, lub podczas próby usunięcia elementu jeśli jest pusta. Sama kolejka oraz jej metody zapewniają synchronizację wątków i jest ona ukryta przez programistą.

Java-wątki Podstawowe metody kolejki blokującej: put – dodaje element; blokuje, jeśli kolejka jest pełna take – usuwa i zwraca element z czoła; blokuje, jeśli kolejka jest pusta

Java-wątki W pakiecie java.util.concurrent znajduje się kilka wersji kolejek blokujących Kolejka LinkedBlockingQueue domyślnie nie posiada ograniczenia, ale można je ustawić.

Java-wątki Kolejka ArrayBlockingQueue ma określoną pojemność i opcjonalny parametr włączający wymóg uczciwości (tj. preferencyjnie dopuszcza te wątki, które czekają najdłużej). Z opcji uczciwości należy korzystać ostrożnie, gdyż może ona znacznie spowolnić działanie programu.

Java-wątki Problem producenta-konsumenta z buforem o pojemności 5 rozwiązany z użyciem kolejek blokujących (Przykład 21)

Java-wątki Kolekcje nie są bezpieczne wątkowo. Mogą zostać uszkodzone, gdy np. jeden wątek zostaje wywłaszczony w trakcie wstawiania bądź usuwania elementów, zanim dokończył przekierowywania łączy. Dlatego dostęp do kolekcji, z której korzysta wiele wątków, musi być synchronizowany

Java-wątki public class ArrayTest { private ArrayList a = new ArrayList(); public void dodaj(Object p, Object d){ synchronized(a){ a.add(p); a.add(d); } public Object get(int nr){ synchronized(a) { return a.get(nr); }

Java-wątki W pakiecie java.util.concurrent znajdują się implementacje map, zbiorów i kolejek, które są całkowicie bezpieczne i specjalnie przeznaczone do pracy w środowisku wielowątkowym: Mapa ConcurrentHashMap Metoda putIfAbsent dodaje nową parę kluczy, jeśli wcześniej ich nie było Metoda remove usuwa parę kluczy (jeśli są dostępne) Obie te metody działają niepodzielnie (Przykład 22)

Java-wątki Zbiór ConcurrentSkipListSet: ConcurrentSkipListSet<E> ls = new ConcurrentSkipListSet<E>(); Gdzie E jest klasą implementującą interfejs Comparable (ponieważ ta kolekcja jest posortowana) Mapa ConcurrentSkipListMap, i jeszcze kilka innych kolekcji

Java-wątki Wszystkie te kolekcje zwracają słabo spójne iteratory, tzn. nie muszą one odzwierciedlać wszystkich wstawień elementów po ich utworzeniu. W przeciwieństwie do iteratorów zwykłych kolekcji, słabo sp. It. nie zgłaszają wyjątku ConcurrentModificationException, jeśli kolekcja zostanie zmodyfikowana po ich utworzeniu.

Java-wątki Kolekcja ConcurrentHashMap może obsłużyć 16 wątków zapisujących działających w tym samym czasie; jeśli ich jest więcej, nadmiar jest tymczasowo blokowany

Java-wątki Istnieje interfejs Callable, podobny do Runnable, posiadający metodę zwracającą wartość (w przeciwieństwie do run) public interface Callable<V> { V call() throws Exception; } Jest to typ parametryzowany

Java-wątki Np. obiekty klasy implementującej Callable<Integer> reprezentują wątki, których wynikiem jest obiekt typu Integer. Istnieje też specjalny interfejs Future, służący do przechowywania wyników obliczeń takich wątków.

Java-wątki public interface Future<V> { V get() throws… void cancel(boolean mayInterrupt); boolean isCancelled(); boolean isDone(); }

Java-wątki Metody obiektów typu Future działają na wątkach typu Callable – czekają na zakończenie ich obliczeń i pobierają od nich wyniki. Metoda get() – jej wywołanie jest zablokowane do zakończenia obliczeń. Druga wersja get – zgłasza wyjątek TimeoutException, jeżeli wątek nie zakończy się przed upływem określonego w argumencie czasu.

Java-wątki Obie metody get wyrzucają wyjątek InterruptedException jeśli wątek na którego obliczenia oczekują zostanie przerwany. Kiedy wątek skończy obliczenia, get natychmiast zwraca odebrany od niego wynik. isDone()-zwraca false jeśli obliczenia wątku jeszcze trwają, true – w p. p.

Java-wątki cancel(boolean myInterrupt) przerywa wątek, jeśli myInterrupt = true. Jeśli wątek jeszcze nie wystartował, zostanie anulowany. Popularną implementacją Future jest klasa FutureTask Scenariusz użycia:

Java-wątki Callable<Integer> watek = new… tu potrzebna klasa implementująca Callable<Integer> FutureTask<Integer> task = new FutureTask<Integer>(watek); Thread t = new Thread(task);//ok., bo FutureTask implementuje także Runnable t.start(); Integer wynik = task.get();//ok., bo FutureTask implementuje Future

Java-wątki Ilustracja do powyższego – Przykład 23 – program obliczający ilość wystąpień zadanego słowa we wszystkich plikach podanego katalogu (i jego podkatalogach)

Java-wątki Ilość wątków działających jednocześnie nie powinna być zbyt duża – może to spowodować znaczne spowolnienie działania a nawet awarię JVM. Problem ten rozwiązują pule wątków. Pula wątków to pewna liczba (ograniczona) wątków nieaktywnych czekających na zadania. Przekazujemy im obiekt typu Runnable, jeden z wątków puli go wykonuje, po czym nie kończy się, lecz czeka na kolejne zadania.

Java-wątki Pule wątków tworzymy statycznymi metodami fabrycznymi klasy Executors. Podstawowe trzy: newCachedThreadPool() – tworzy pulę do wykonywania wielu krótkotrwałych zadań. Wątki z tej puli, które już wykonały zadanie, czekają na kolejne (maks.60s);gdy zabraknie wątków do zadań, dynamicznie tworzone są nowe.

Java-wątki newFixedThreadPool – tworzy pulę o ustalonej liczbie wątków. Nieaktywne wątki są zachowywane bezterminowo. newSingleThreadExecutor – pula złożona z jednego wątku wykonującego zadania po kolei Wszystkie te metody zwracają pulę wątków – obiekt klasy ThreadPoolExecutor, implementującej interfejs ExecutorService

Java-wątki Interfejs ten zawiera metodę submit, służącą do przekazywania do puli wątków zadań: Future<?> submit(Runnable task) – przekazuje obiekt task do wykonania przez pulę i zwraca obiekt Future, dzięki któremu można kontrolować status wykonania naszego zadania (isDone, cancel, isCancelled); metoda get po zakończniu zadania zwraca null (bo task nie zwraca żadnej wartości, nie jest typu Callable)

Java-wątki Future<T> submit(Callable task) – przekazuje do wykonania obiekt typu Callable, zwraca obiekt typu Future, na którym możemy wywołać get i czekać, aż zwróci ona wynik działania wątku task Po zakończeniu działania puli wywołujemy shutdown() która zamyka pulę wątków. Zadania które czekają jeszcze w kolejce (bo było w puli za mało wątków by je od razu wykonać) będą jeszcze (po wywołaniu shutdown) wykonane, jednak żadne nowe nie są już przyjmowane.

Java-wątki Scenariusz użycia puli wątków: Wywołanie statycznej metody newCachedThreadPool lub newFixedThreadPool z klasy Executors Przekazanie obiektu Runnable lub Callable za pomocą submit. Korzystanie ze zwróconego obiektu Future: anulowanie zadania, odebranie wyniku itp. shutdown

Java-wątki Scenariusz z przykładu 24: mamy klasę MatchCounter typu Callable. ExecutorService pool = Executors.newCachedThreadPool(); MatchCounter<String> counter = new MatchCounter<String>(…); Future<Integer> result = pool.submit(counter); Integer w = result.get(); pool.shutdown()

Java-wątki Interfejs ExecutorService posiada metodę invokeAny, która przekazuje do puli wszystkie obiekty z kolekcji typu Callable i zwraca wynik ukończonego zadania (nie wiadomo którego, prawdopodobnie pierwszego ukończonego): List<Callable<String>> zadania = new … ExecutorService pula = Executors.newCachedThreadPool(); String wynik = pula.invokeAny(zadania);

Java-wątki invokeAny stosuje się przy zadaniach typu rozkład liczby na czynniki pierwsze (łamanie szyfru RSA): wątki z kolekcji próbują rozkładu przy użyciu liczb z innego zakresu; kiedy którykolwiek z nich da odpowiedź, dalsze obliczenia można zatrzymać Metoda invokeAll przesyła wszystkie obiekty Callable z kolekcji i zwraca listę obiektów Future, dzięki którym możemy odebrać wyniki obliczone przez wątki.

Java-wątki List<Callable<T>> zadania = new … ExecutorService pula = Executors.newCachedThreadPool(); List<Future<T>> wyniki = pula.invokeAll(zadania); for(Future<T> wsk : wyniki) System.out.println(wsk.get());

Java-wątki Wadą powyższego rozwiązania jest to, że jeśli pierwszy wątek z listy działa długo, niepotrzebnie na niego czekamy, choć w tym czasie moglibyśmy odebrać wyniki od wielu wcześniej od niego zakończonych wątków. Rozwiązaniem tego problemu jest użycie klasy ExecutorCompletionService Tworzymy obiekt tej klasy, przekazując do konstruktora pulę wątków. Obiekt ten zarządza kolejką blokującą zawierającą obiekty typu Future, w których przechowywane są wyniki obliczeń. Powyższy przykład będzie wyglądał następująco:

Java-wątki List<Callable<T>> zadania = new … ExecutorService pula = Executors.newCachedThreadPool(); ExecutorCompletionService ecs = new ExecutorCompletionService(pula); for(Callable<T> z:zadania) ecs.submit(z); for(int i = 0;i < zadania.size();i++) wykonaj(ecs.take().get());

Przykłady Przykłady-wątki.rar