Wątki w Javie
Transkrypt
Wątki w Javie
Wątki w Javie Piotr Tokarski Wprowadzenie Co to są wątki? Co to są wątki? ● Każdy program ma przynajmniej jeden wątek Co to są wątki? ● ● Każdy program ma przynajmniej jeden wątek Wątki są po to, by symulować równoległe wykonywanie czynności Co to są wątki? ● ● ● Każdy program ma przynajmniej jeden wątek Wątki są po to, by symulować równoległe wykonywanie czynności Nikt nie może przewidzieć jaka będzie kolejność przydzielania procesora poszczególnym wątkom Co to są wątki? ● ● ● ● Każdy program ma przynajmniej jeden wątek Wątki są po to, by symulować równoległe wykonywanie czynności Nikt nie może przewidzieć jaka będzie kolejność przydzielania procesora poszczególnym wątkom Wątki to bardzo rozległy i problematyczny temat Wątki w Javie Wątki w Javie ● Komponenty wspierające wielowątkowość znajdują się w pakiecie java.lang Wątki w Javie ● ● Komponenty wspierające wielowątkowość znajdują się w pakiecie java.lang Kluczowa klasa to java.lang.Thread Wątki w Javie ● ● ● Komponenty wspierające wielowątkowość znajdują się w pakiecie java.lang Kluczowa klasa to java.lang.Thread Istotną rolę w działaniach wielowątkowych odgrywa interfejs java.lang.Runnable Wątki w Javie ● ● ● ● Komponenty wspierające wielowątkowość znajdują się w pakiecie java.lang Kluczowa klasa to java.lang.Thread Istotną rolę w działaniach wielowątkowych odgrywa interfejs java.lang.Runnable Każdy obiekt posiada zbiór metod wspierających wielowątkowość Kluczowe sterowanie class Object class Thread interface Runnable wait start run notify join notifyAll yield sleep Kluczowe sterowanie class Object class Thread interface Runnable wait start run notify join notifyAll yield sleep ● Metody zaznaczone kursywą to metody statyczne Kluczowe sterowanie class Object class Thread interface Runnable wait start run notify join notifyAll yield sleep ● Metody zaznaczone kursywą to metody statyczne ● Każdy wątek jest również java.lang.Runnable Uruchamianie wątków Uruchamianie wątków Sposób I Uruchamianie wątków Sposób I ● Zostaje stworzona klasa dziedzicząca po klasie java.lang.Thread i przeciążająca metodę public void run() Uruchamianie wątków Sposób I ● ● Zostaje stworzona klasa dziedzicząca po klasie java.lang.Thread i przeciążająca metodę public void run() Zostaje stworzony obiekt klasy dziedziczącej z java.lang.Thread Uruchamianie wątków Sposób I ● ● ● Zostaje stworzona klasa dziedzicząca po klasie java.lang.Thread i przeciążająca metodę public void run() Zostaje stworzony obiekt klasy dziedziczącej z java.lang.Thread Zostaje uruchomiona metoda public synchronized void start() Uruchamianie wątków Sposób I DEMO Uruchamianie wątków Sposób II Uruchamianie wątków Sposób II ● Zostaje stworzona klasa implementująca interfejs java.lang.Runnable (metodę void run()) Uruchamianie wątków Sposób II ● ● Zostaje stworzona klasa implementująca interfejs java.lang.Runnable (metodę void run()) Zostaje stworzony obiekt klasy implementującej java.lang.Runnable Uruchamianie wątków Sposób II ● ● ● Zostaje stworzona klasa implementująca interfejs java.lang.Runnable (metodę void run()) Zostaje stworzony obiekt klasy implementującej java.lang.Runnable Zostaje stworzony obiekt klasy java.lang.Thread, której konstruktor przyjmuje obiekt klasy implementującej java.lang.Runnable Uruchamianie wątków Sposób II ● ● ● ● Zostaje stworzona klasa implementująca interfejs java.lang.Runnable (metodę void run()) Zostaje stworzony obiekt klasy implementującej java.lang.Runnable Zostaje stworzony obiekt klasy java.lang.Thread, której konstruktor przyjmuje obiekt klasy implementującej java.lang.Runnable Zostaje uruchomiona metoda public synchronized void start() Uruchamianie wątków Sposób II DEMO Uruchamianie wątków Uruchamianie wątków ● Zobaczmy dlaczego oba sposoby są możliwe Uruchamianie wątków ● ● Zobaczmy dlaczego oba sposoby są możliwe Mimo, że oba sposoby działają tak samo, pierwszy sposób jest uważany za przestarzały i sugerowane jest używanie sposobu drugiego (z jawną implementacją interfejsu java.lang.Runnable) Uruchamianie wątków ● UWAGA!!! Jawne uruchomienie metody void run() NIE TWORZY nowego wątku Uruchamianie wątków ● ● UWAGA!!! Jawne uruchomienie metody void run() NIE TWORZY nowego wątku Wywołanie metody public synchronized void start() uruchamia metodę void run() w nowo utworzonym wątku Uruchamianie wątków ● UWAGA!!! Na każdym obiekcie typu java.lang.Thread metoda public synchronized void start() może być uruchomiona TYLKO RAZ Uruchamianie wątków ● ● UWAGA!!! Na każdym obiekcie typu java.lang.Thread metoda public synchronized void start() może być uruchomiona TYLKO RAZ Każde kolejne wywołanie metody public synchronized void start() na tym samym obiekcie klasy java.lang.Thread spowoduje rzucenie wyjątku typu java.lang.IllegalThreadStateException Kluczowe sterowanie class Object class Thread wait start notify join notifyAll yield sleep interface Runnable ✓ run ✓ Głodzenie wątków Głodzenie wątków Głodzenie wątków ● Głodzenie jest naszym celem, gdy chcemy wymusić wykonywanie w danym momencie określonych wątków, a inne zatrzymać Głodzenie wątków Sposób I Głodzenie wątków Sposób I ● public static native void sleep(long millis) throws InterruptedException Głodzenie wątków Sposób I ● ● public static native void sleep(long millis) throws InterruptedException Najprostszy sposób Głodzenie wątków Sposób I ● ● ● public static native void sleep(long millis) throws InterruptedException Najprostszy sposób AKTUALNY wątek zostaje uśpiony na konkretny, wskazany okres czasu Głodzenie wątków Sposób I ● ● ● ● public static native void sleep(long millis) throws InterruptedException Najprostszy sposób AKTUALNY wątek zostaje uśpiony na konkretny, wskazany czas Istnieje przeładowanie metody: public static void sleep(long millis, int nanos) throws InterruptedException Głodzenie wątków Sposób II Głodzenie wątków Sposób II ● public static native void yield() Głodzenie wątków Sposób II ● public static native void yield() ● Yield – ustąpić Głodzenie wątków Sposób II ● public static native void yield() ● Yield – ustąpić ● AKTUALNY wątek ustępuje sterowania pozostałym Głodzenie wątków Sposób II ● public static native void yield() ● Yield – ustąpić ● AKTUALNY wątek ustępuje sterowania pozostałym ● Komenda jest tylko „prośbą” do procesora Głodzenie wątków Sposób III Głodzenie wątków Sposób III ● public final void join() Głodzenie wątków Sposób III ● ● public final void join() Aktualny wątek oczekuje aż wątek, na którym została uruchomiona metoda zakończy swoją pracę i „dołączy” do aktualnego wątku Głodzenie wątków Sposób III ● ● ● public final void join() Aktualny wątek oczekuje aż wątek, na którym została uruchomiona metoda zakończy swoją pracę i „dołączy” do aktualnego wątku Istnieją przeładowania metody: public final synchronized void join(long millis) public final synchronized void join(long millis, int nanos) Kluczowe sterowanie class Object class Thread interface Runnable wait start ✓ notify join ✓ notifyAll yield ✓ sleep ✓ run ✓ Głodzenie wątków Sposób IV Głodzenie wątków Sposób IV ● Słowo kluczowe synchronized Głodzenie wątków Sposób IV ● ● Słowo kluczowe synchronized Blok/metoda zaczyna być traktowana jako jednostkowa operacja procesora Głodzenie wątków Sposób IV ● ● ● Słowo kluczowe synchronized Blok/metoda zaczyna być traktowana jako jednostkowa operacja procesora UWAGA!!! Nieumiejętne używanie bloków synchronicznych może doprowadzić do tzw. „deadlock-ów” Głodzenie wątków Sposób IV ● Kod synchroniczny można odblokować metodą obiektu public final void wait() Głodzenie wątków Sposób IV ● ● Kod synchroniczny można odblokować metodą obiektu public final void wait() Aby ponownie ustawić blokadę należy skorzystać z metody public final native void notify() Głodzenie wątków Sposób IV ● ● ● Kod synchroniczny można odblokować metodą obiektu public final void wait() Aby ponownie ustawić blokadę należy skorzystać z metody public final native void notify() public final native void notifyAll() informuje wszystkie oczekujące wątki Głodzenie wątków Sposób IV ● ● ● ● Kod synchroniczny można odblokować metodą obiektu public final void wait() Aby ponownie ustawić blokadę należy skorzystać z metody public final native void notify() public final native void notifyAll() informuje wszystkie oczekujące wątki Metoda wait mają następujące przeładowania: public final native void wait(long timeout) throws InterruptedException public final void wait(long timeout, int nanos) throws InterruptedException Kluczowe sterowanie class Object class Thread interface Runnable wait ✓ start ✓ notify ✓ join ✓ notifyAll ✓ yield ✓ sleep ✓ run ✓ Dziękuję za uwagę