Język Java Wielowątkowość.

Slides:



Advertisements
Podobne prezentacje
Wstęp do strumieni danych
Advertisements

C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Związki w UML.
Podstawowe pojęcia programowania współbieżnego
Programowanie wielowątkowe
Java dla studentów II roku Wydziału Fizyki PW Przemysław Duda, 2012
Jarosław Kuchta Monitory.
Programowanie obiektowe
Programowanie obiektowe
Programowanie obiektowe
Wzorce.
Tworzenie i obsługa programów – przykład 3 uwagi cd. Wykorzystując różne klasy biblioteki języka Java należy pamiętać w jakim pakiecie się znajdują. Wszystkie.
Nguyen Hung Son Uniwersytet Warszawski
Programowanie obiektowe w Javie
Podstawy języka Java Nguyen Hung Son Uniwersytet Warszawski.
RMI I RMI-IIOP Wprowadzenie Co to jest RMI?
Programowanie wielowątkowe
Multimedia Obrazy i dźwięki w apletach Javy, praca z tekstem, zdarzenia od myszki, obsługa wyjątków w Javie, aplety z wątkami, animacja poklatkowa.
Programowanie sieciowe w Javie
Wprowadzenie do SystemC
Systemy operacyjne Wykład nr 5: Wątki Piotr Bilski.
Systemy operacyjne Wykład nr 4: Procesy Piotr Bilski.
C++ wykład 2 ( ) Klasy i obiekty.
Gniazda komunikacji sieciowej w języku Java
Tablice tablica jest sekwencją elementów tego samego typu (prostego lub obiektowego) w Javie tablice są obiektami, a zmienne tablicowe przechowują referencję
Wieloprocesowy system operacyjny dla komputerów ATARI XL/XE
Wątki.
Pakiety w Javie Łukasz Smyczyński (132834). Czym są pakiety? Klasy w Javie są grupowane w pewne zbiory zwane pakietami. Pakiety są więc pewnym podzbiorem.
Java 3 MPDI Programowanie obiektowe W7. import java.io.*; public class X { // kontrukcja throws – określenie jakie wyjątki może dana metoda // sygnalizować
W większości języków programowania biblioteki wejścia/wyjścia ukrywają szczegóły obsługi poszczególnych mediów pod abstrakcją strumienia (ang. stream).
Systemy operacyjne.
Budowa systemu komputerowego
SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE
Tworzenie aplikacji mobilnych
Automatyka i Robotyka Systemy czasu rzeczywistego Wykład 4.
Programowanie obiektowe – zastosowanie języka Java SE
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Inicjalizacja i sprzątanie
Seminarium problemowe
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 7 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/20 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Problem sekcji krytycznej
Przerwanie ang. interrupt.
Programowanie obiektowe 2013/2014
Programowanie sieciowe w Javie
W ą t e k (lekki proces) thread.
SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE
Kurs języka C++ – wykład 4 ( )
Procesy, wątki Program a proces Proces: Przestrzeń adresowa, kod, dane, stos (część pamięci do przechowania zmiennych lokalnych i niektórych adresów) Otwarte.
Model współbieżności w Javie autor: Grzegorz Szuba.
Model współbieżności w Javie
Uniwersytet Łódzki Wydział Matematyki i Informatyki, Katedra Analizy Nieliniowej Programowanie wielowątkowe w Javie Wykład 9 mgr inż. Michał Misiak.
Paweł Starzyk Obiektowe metody projektowania systemów
Programowanie sieciowe w Javie Michał Kuciapski
ASP.NET Dostęp do bazy danych z poziomu kodu Elżbieta Mrówka-Matejewska.
Programowanie Obiektowe – Wykład 6
Wątki, programowanie współbieżne
Klasy, pola, obiekty, metody. Modyfikatory dostępu, hermetyzacja
(według:
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Programowanie obiektowe – zastosowanie języka Java SE
PGO Interfejsy Michail Mokkas.
Założenia projektowe Javy
Zastosowanie tzw reaktywności w aplikacjach.
Tworzenie wątków w Javie
Zapis prezentacji:

Język Java Wielowątkowość

Wątki Podział programu na kawałki, z których każdy uruchamia się na innym procesorze, np. serwery WWW – oprogramowanie dzielące zadania – obsługę poszczególnych użytkowników Wątek (ang. thread) – wykonuje zadanie działając niezależnie od głównego programu, pojedynczy sekwencyjny przepływ sterowania w obrębie procesu Z punktu widzenia użytkownika - jednoczesne wykonywanie wielu czynności

Programowanie współbieżne Obsługa każdego wątku przez odrębny procesor (tzw. programowanie równoległe) Więcej wątków niż procesorów - emulowanie współbieżności Cechy programowania współbieżnego polepszenie zarządzania zasobami większa wygoda użytkownika emulacja - zmniejszenie wydajności

Szybsze wykonanie zadań Na jednym procesorze konieczne jest przełączanie kontekstu powodujące narzut – opłaca się tylko wtedy gdy wątek jest blokowany np. poprzez operacje I/O Od JDK 1.4 nieco porawione przełączanie między wątkami tak, aby wszystkie były równouprawnione Niektóre programy są wielowątkowe z założenia – servlet

Szybsze wykonanie zadań Przykładem wykorzystania wielowątkowości jest programowanie sterowane zdarzeniami – program wykonuje obliczenia i reaguje na działania użytkownika W przypadku systemu operacyjnego współbieżność realizowana jest na poziomie procesu (programu z przydzieloną pamięcią) Java nie rozwidla procesów, ale tworzy wiele wątków w jednym procesie – uniezależnienie od systemu operacyjnego

Wielowątkowość w Javie Język tworzy osobny stos i osobne rejestry dla każdego wątku koordynuje i szereguje wątki odśmiecacz (garbage collector) nie usuwa wątków nawet gdy nie ma do nich referencji Szeregowanie wątków - określanie dostępu do procesora pierwszeństwo - wątki o wyższym priorytecie wątki równoprawne - przełączane na zmianę

Programowanie wątków Klasa java.lang.Thread klasa bazowa wątków zawiera metody konieczne do obsługi wątków Główne metody wątku (domyślnie puste) run() - określa zachowanie wątku (zadanie do wykonania) start() - uruchamia wątek, wywołuje run() Metody programowania wątków utworzenie klasy pochodnej po Thread implementacja interfejsu Runnable w celu utworzenia zadania przekazywanego następnie do wątku (obiektu klasy Thread) lub wykonawcy (java.util.concurrent.Executor (SE5))

Cykl życia wątku run() start() nowy wątek wątek uruchamialny blokowanie nowy wątek wątek uruchamialny wątek zablokowany zakończenie metody run() wątek uśmiercony

Dziedziczenie po klasie Thread - aplikacja TestWatkow class MojWatek extends Thread { int numer; public MojWatek(int numer) { super(); this.numer = numer; } public void run() { System.out.println("Watek: " + numer);

public class TestWatkow { public static void main(String args[]) { MojWatek w1, w2, w3; w1 = new MojWatek(1); w2 = new MojWatek(2); w3 = new MojWatek(3); w1.start(); w2.start(); w3.start(); System.out.println("Watek: 0"); }

Użycie interfejsu Runnable Zastosowanie - w klasach mających klasę bazową Implementacja interfejsu w klasie głównej - zawiera tę samą metodę run() Tworzenie wątku - obiektu klasy Thread Argument konstruktora - obiekt klasy, w której określono metodę run() wątku Często wewnątrz metody run występuje pętla nieskończona wykonująca zadania dopóki wątek jest nam potrzebny, wtedy konieczne jest zastosowanie warunku powrotu z return, dodatkowo w pętli może być dodana instrukcja Thread.yeld() sugestia dla thread schedulera (planisty) żeby przełączył na chwilę na inny wątek

Użycie wykonawcy (od JDK 1.5) Obiekt Executor pośredniczy pomiędzy klientem a wykonaniem zadania – nie wywołujemy zadania bezpośrednio Eliminuje konieczność jawnego zarządzania cyklem życia wątku i synchronizacji wątków przy dostępie do zasobów współdzielonych Klasa ExecutorService konstruuje kontekst uruchomienia zadania (Runnable) – obiekt tej klasy tworzony jest poprzez klasę Executors: Executors.newCachedThreadPool()- dodaje do puli kolejne wątki wykonujące kolejne zadania, gdy zwolni się jakiś wątek kolejne zadanie przypisywane jest do niego

Użycie wykonawcy II Executors.newFixedThreadPool(int)- rozmiar puli jest od razu ustalony – strata z narzutu na tworzenie wątków ponoszona tylko raz na początku podczas tworzenia puli – najlepsze rozwiązanie w kodzie produkcyjnym – watki obsługiwane są szybciej, uniemożliwia przekroczenie dopuszczalnej przez podsystem ilości wątków – lepsze zarządzanie obsługą zdarzeń Executors.newSingleThreadExecutor()- pula wątków uruchamiająca jeden wątek jednocześnie – umożliwia zsynchronizowany dostęp do wspólnych zasobów np. drukarki, tworzy niejawną kolejkę w której umieszczane są zadania i wykonywane kolejno; mamy pewność że nie uszkodzimy systemu plików Executors.newSingleThreadScheduledExecutor() – umożliwia uruchamianie zadań z opóźnieniem lub cyklicznie Executors.newScheduledThreadPool(int) Metoda executor.shutdown() – blokada wykonania kolejnych wątków przez wykonawcę

Użycie wykonawcy - przykład import java.util.concurrent.*; public class NoweWatki{ public static void main(String args[]){ ExecutorService exe = Executors.newFixedThreadPool(2); for(int i=0; i<2; i++){ exe.execute(new ObiektRunnable()); } exec.shutdown();

Zadania zwracające wartość (JDK 1.5) Implementacja interfejsu Runnable nie zwraca wartości – metoda public void run() W celu zwrócenia wartości – zastosowanie interfejsu Callable oraz metody call() zastępującej run(), zadanie uruchamiane za pomocą metody submit()rozszerzającą możliwości metody execute interfejsu ExecutorService Wynik submit() – obiekt Future który można wykorzystać do przerwania zadania albo odczekania do zakończenia jego wykonywania cancel(boolean) – true –przerwanie wątku zadania, false – odczekanie do zakończenia jeśli już uruchomione isCancelled(), isDone(), get() – czeka i zwraca wynik

Zadania zwracające wartość import java.util.concurrent.*; class Zadanie implements Callable<String>{ public String call(){ return „Wynik wywołania zadania w wątku” } public class TestZadania{ public static void main(String[] args){ ExecutorService exe = Executors.newCachedThreadPool(); Future<String> fut = exe.submit(new Zadanie()); System.out.println(fut.get()); //fut.get(long czas, //TimeUnit tu) } //tu = TimeUnit.MILISECONDS lub NANOSECONDS lub //MICROSECONDS lub SECONDS – zwraca wynik jeśli jest

Metody blokowania wątków Uśpienie na n milisekund - wywołanie metody sleep(n), np. try { //dawniej Thread.sleep(1000); TimeUnit.SECONDS.sleep(1); //JDK 1.5 }catch (InterruptedException e){ } //sleep nie zwalnia blokady obiektu Zawieszenie wykonania (tylko wewnątrz metody synchronizowanej) - wywołanie metody wait() Automatyczne - przy operacjach We/Wy

Wątki w apletach - animacje Etapy tworzenia animacji tworzenie rysunku („ramki” animacji) wyświetlenie ramki - złudzenie ruchu Użycie metod apletu start() - tworzenie nowego wątku apletu (możliwość wykonywania współbieżnie z innymi programami w systemie) stop() - zatrzymuje wątek

Aplet Zegar (cz. 1) import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.util.*; import java.text.DateFormat; public class Zegar extends JApplet implements Runnable { JLabel napis = new JLabel("", JLabel.CENTER); Thread watek;

Aplet Zegar (cz. 2) public void init() { Font f = new Font("serif", Font.BOLD, 24); Container kont = getContentPane(); napis.setOpaque(true); napis.setFont(f); napis.setBackground(Color.lightGray); napis.setForeground(Color.red); Border b = BorderFactory.createRaisedBevelBorder(); napis.setBorder(b); kont.add(napis, BorderLayout.CENTER); }

Aplet Zegar (cz. 3) public void start() { // metoda apletu if (watek == null) { watek = new Thread(this); watek.start(); } public void stop() { // metoda apletu if (watek != null) { watek = null;

Aplet Zegar (cz. 4) public void run() { // metoda wątku Thread watekAktualny = Thread.currentThread(); while (watek == watekAktualny) { Calendar cal = Calendar.getInstance(); Date data = cal.getTime(); DateFormat df = DateFormat.getTimeInstance(); napis.setText(df.format(data)); napis.repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { } }

Priorytety wątków Metody obsługi priorytetów (w praktyce rzadko używane) odczytanie priorytetu - getPriority() ustawianie priorytetu - setPriority() Argument metod - liczba całkowita z zakresu od Thread.MIN_PRIORITY do Thread.MAX_PRIORITY (JDK – 10 poziomów, Sun Solaris 2^31) Jeżeli chcemy ustawić dla bieżącego wątku możemy go uzyskać za pomocą Thread.currentThread()

Wątki demony Demon – wątek działający w tle programu nie związany bezpośrednio z jego głównymi zadaniami Program kończy swoje działanie kiedy zakończą się wszystkie wątki nie będące demonami Ustawienie demoniczności wątku metoda setDaemon(boolean) – można ją wywołać zanim wątek zostanie uruchomiony (metodą start()) Metoda isDeamon() – sprawdza demoniczność Każdy wątek wywołany z demona także jest demonem W przypadku gdy używamy Executora konieczność stworzenia własnej fabryki wątków – klasy implementującej interfejs ThreadFactory (zawierającej metodę Thread newThread(Runnable r)), której obiekt możemy użyć w metodzie execute(new MojaFabryka())

Synchronizacja wątków Konieczność - np. współdzielenie zasobów (sekcja krytyczna - izolowana część kodu) Sposoby synchronizacji blokowanie obiektu - użycie w różnych wątkach tzw. metod synchronizowanych blokowanie obiektu i wątku - użycie w metodach synchronizowanych metod wait() i notify()

Metody synchronizowane Określone modyfikatorem synchronized, np. public synchronized int czytaj() ( ... } public synchronized void pisz(int x) { ... } Wywołanie metody - dla pewnego obiektu Wynik - blokada danego obiektu dla innych metod synchronizowanych

Użycie metod wait() i notify() Blokowanie i obiektu, i wątku na nieokreślony czas - wait() – zwalnia blokadę obiektu na n milisekund - wait(n) Od JDK 1.5 klasa java.util.concurrent.locks.Condition i metoda await() Ponowne uruchamianie wątku notify() - zdejmuje blokadę z danego wątku notifyAll() - odblokowuje wszystkie wątki oczekujące na dany obiekt –lepiej użyć tej metody bo nie wiemy ile zadań oczekuje po upływie n milisekund Od JDK 1.5 klasa Condition i metoda signal() Wszystkie metody - klasy java.lang.Object nie Thread – bo operują blokadą, która jest częścią każdego obiektu Wywołanie w metodzie niesynchronizowanej – IllegalMonitorStateException, „Current thread not owner”

Przykład Producent-Klient generuje liczbę z przedziału 0÷9 zapisuje ją w obiekcie klasy Dane wyświetla wygenerowaną liczbę wykonuje czynności nieregularnie - zasypia" na przypadkowy czas z zakresu 0÷100 [ms] Klient wczytuje liczbę z obiektu klasy Dane wyświetla wczytaną liczbę

Klasa Producent class Producent extends Thread { private Dane dane; public Producent(Dane c) { dane = c; } public void run() { for (int i = 0; i < 10; i++) { dane.pisz(i); try { sleep((int)(Math.random()*100)); } catch (InterruptedException e) {} }

Klasa Klient class Klient extends Thread { private Dane dane; public Klient(Dane c) { dane = c; } public void run() { int x = 0; for (int i = 0; i < 10; i++) { x = dane.czytaj(); }

Producent-Klient: klasa Dane public class Dane { private int d; private boolean dostepne = false; public synchronized int czytaj() { while (dostepne == false) { try { wait(); } catch (InterruptedException e) {} } System.out.println("Odczyt: " + d); dostepne = false; notifyAll(); return d;

public synchronized void pisz(int x) { while (dostepne == true) { try { wait(); } catch (InterruptedException e) {} } System.out.println("Zapis: " + x); d = x; dostepne = true; notifyAll();

Producent-Klient: aplikacja TestPK public class TestPK { public static void main(String[] args){ Dane d = new Dane(); Producent p1 = new Producent(d); Klient k1 = new Klient(d); p1.start(); k1.start(); }

Własna blokada (od 1.5) import java.util.concurrent.locks.*; public class Blokada { private int wartosc; private Lock blokada = new ReentrantLock(); public void zwieksz(){ blokada.lock();//blokada.tryLock(czas, TimeUnit) try{ ++wartosc; }finally{ blokada.unlock(); } public static void main(String[] args){ …

Wątki w Swingu Rodzaje wątków w Swingu Wątki inicjujące - Initial threads – uruchamiające aplikacje, wywołujące metodę main, init (applet), w Swingu tworzą obiekt Runnable inicjalizujący GUI i przekazują do wykonania w wątku event dispatch Wątki wysyłające zdarzenia – Event dispatch thread – wykonują obsługę zdarzeń Wątki działające w tle – Worker hreads – javax.swing.SwingWorker, metoda done

Wątki w Swingu Zasada naczelna: unikać wątków, jeśli to możliwe bo Swing uruchamia własny wątek aktualizujący interfejs podczas działania uzytkownika i może dojść do zakleszczeń Wykonywanie kodu zależnego od stanu zrealizowanego komponentu (wyświtlonego) - tylko w wątku wysłanym przez zdarzenie (ang. event-dispatching thread) w tym wątku inne wątki np. wątek z main powinny umieszczać zadania Nie umieszczać długich wykonań w wątku rozprowadzającym zdarzenia (w metodzie obsługi zdarzenia) – nie może odrysować komponentów Komponent zrealizowany - narysowany lub gotowy do narysowania

Wątki w Swingu Uaktualnienie komponentu bez obsługi zdarzenia - metody klasy SwingUtilities z pakietu javax.swing - invokeLater() lub invokeAndWait() Uaktualnianie komponentów z opóźnieniem lub co pewien czas - klasa Timer

Wątki w Swingu public class Etykietka{ public static void main(String[] args){ JFrame f = new JFrame(); JLabel et = new JLabel(); f.add(et); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); TimeUnit.SECONDS.sleep(3); SwingUtilities.invokeLater(new Runnable(){ public void run(){ et.setText(„Witam po trzech sekundach!”): } });

Klasy Timer i TimerTask Dodane w wersji 1.3 (pakiet java.util) Programowanie wątków utworzenie klasy potomnej po TimerTask przesłonięcie metody run() utworzenie obiektu wątku klasy Timer utworzenie obiektu klasy potomnej po TimerTask (zadania) określenie sposobu wykonywania zadania

Klasy Timer i TimerTask Wykonywanie zadania - metoda schedule() opóźnienie o n milisekund schedule(TimerTask zadanie, long n) uruchomienie o określonej porze schedule(TimerTask zadanie, Date d) powtarzanie co x milisekund, np. schedule(TimerTask zadanie, long n, long x) Zatrzymywanie wątku - metoda cancel()

Problemy z wątkami Impas (ang. deadlock) - zamknięta pętla wątków, czekających na siebie nawzajem Programy wykorzystujące wątki skomplikowane utrudnione wykrywanie błędów