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ę