Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Język Java Wielowątkowość. 2 Wątki Podział programu na kawałki, z których każdy uruchamia się na innym procesorze, np. serwery WWW – oprogramowanie dzielące.

Podobne prezentacje


Prezentacja na temat: "Język Java Wielowątkowość. 2 Wątki Podział programu na kawałki, z których każdy uruchamia się na innym procesorze, np. serwery WWW – oprogramowanie dzielące."— Zapis prezentacji:

1 Język Java Wielowątkowość

2 2 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

3 3 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

4 4 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

5 5 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

6 6 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ę

7 7 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))

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

9 9 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); }

10 10 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"); }

11 11 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

12 12 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

13 13 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ę

14 14 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(); }

15 15 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

16 16 Zadania zwracające wartość import java.util.concurrent.*; class Zadanie implements Callable { 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 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 }

17 17 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

18 18 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

19 19 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;

20 20 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. 2)

21 21 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. 3)

22 22 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) { } } Aplet Zegar (cz. 4)

23 23 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()

24 24 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())

25 25 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()

26 26 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

27 27 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

28 28 Przykład Producent-Klient Producent –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ę

29 29 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) {} }

30 30 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(); }

31 31 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; }

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

33 33 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(); }

34 34 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){ … }

35 35 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

36 36 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

37 37 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

38 38 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!): } }); }

39 39 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

40 40 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()

41 41 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


Pobierz ppt "Język Java Wielowątkowość. 2 Wątki Podział programu na kawałki, z których każdy uruchamia się na innym procesorze, np. serwery WWW – oprogramowanie dzielące."

Podobne prezentacje


Reklamy Google