model współbieżności w javie
DESCRIPTION
Model współbieżności w Javie. autor: Grzegorz Szuba. Współbieżność - a co to takiego?. Współbieżność to jednoczesne wykonywanie współpracujących i komunikujących się ze sobą wątków W komputerach jednoprocesorowych współbieżność jest emulowana, w danym momencie wykonywany jest tylko jeden wątek. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/1.jpg)
Model współbieżności w Javie
autor: Grzegorz Szuba
![Page 2: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/2.jpg)
Współbieżność - a co to takiego?
• Współbieżność to jednoczesne wykonywanie współpracujących i komunikujących się ze sobą wątków
• W komputerach jednoprocesorowych współbieżność jest emulowana, w danym momencie wykonywany jest tylko jeden wątek
![Page 3: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/3.jpg)
Różnice między wątkiem a procesem
• Każdy wątek posiada własny wirtualny procesor
• Wątki korzystają z tego samego egzemplarza kodu wykonywalnego
• Wątki korzystają z tych samych danych
![Page 4: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/4.jpg)
Jak stworzyć nowy wątek?
• Dziedzicząc po klasie Thread
• Implementując interfejs Runnable
![Page 5: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/5.jpg)
Dziedziczenie po klasie Thread
• public class MyThread extends Thread {• public void run() {
System.out.println(”Hello world”);
}
• Thread nowy = new MyThread();
nowy.start();
![Page 6: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/6.jpg)
Dziedziczenie po klasie Thread
• Należy pamiętać, że w Javie można dziedziczyć tylko po jednej klasie
• Jeśli potrzebujemy dziedziczyć po innej klasie, możemy zaimplementować interfejs Runnable
![Page 7: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/7.jpg)
Implementacja interfejsu Runnable
• public class myLabel extends Label implements Runnable {
• public void run(){setText(”Hello world”);
}
• myLabel nowy = new MyLabel();Thread nowywatek = new Thread(nowy);nowywatek.start();
![Page 8: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/8.jpg)
Stany wątków
• nowy
• uruchamialny
• zablokowany
• uśmiercony
![Page 9: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/9.jpg)
Stany wątków - nowy• Obiekt wątku już istnieje, ale jeszcze się nie
wykonuje• Aby rozpocząć wykonywanie, należy
wywołać funkcję start()public void start()
throws IllegalThreadStateException
• wyjątek zostanie rzucony, gdy na rzecz danego obiektu wywoływano już metodę start()
![Page 10: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/10.jpg)
Stany wątków - uruchamialny
• Wątek jest uruchomiony – wywołano już na jego rzecz metodę start() i jeśli właśnie nie działa, to tylko dlatego, że oczekuje na przydział zasobów
![Page 11: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/11.jpg)
Stany wątków - zablokowany
• Do sterowania wykonywaniem wątków możemy użyć następujących instrukcji:
• sleep()
• wait()
• notify(), notifyAll()
• join()
• yield()
![Page 12: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/12.jpg)
Metoda sleep()
• public static void sleep(long millis)throws
InterruptedException • public static void sleep(long millis,int
nans) throws InterruptedException
• Nie jest zwalniana blokada obiektu• Wyjątek zostanie rzucony, gdy inny wątek
wywoła metodę interrupt() na rzecz tego wątku
![Page 13: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/13.jpg)
Metoda interrupt()
• public void interrupt()• Przerywa zawieszenie wątku
metodami sleep, wait i join na rzecz którego jest wywołana
• Przerwany wątek otrzyma wyjątek InterruptedException
![Page 14: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/14.jpg)
Metoda join()
• Wywołując metodę join() innego wątku, zawieszamy wątek aż do zakończenia wykonania wątku, którego metodę wywołaliśmy
• Jeśli podamy argument czasowy, wątek będzie czekał tylko przez określony czas
![Page 15: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/15.jpg)
Metoda join()
• public final void join()throws
InterruptedException• public final void join(long millis)
throws InterruptedException
• public final void join(long millis, int nanos) throws InterruptedException
• Wyjątek zostanie rzucony, gdy inny wątek wywoła metodę interrupt() na rzecz tego wątku
![Page 16: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/16.jpg)
Metoda yield()
• public static void yield() • Przerywa wykonanie wątku aby umożliwić
innym wątkom wykonywanie się• Dotyczy to tylko wątków o takim samym
lub większym priorytecie• Wątek od razu znajduje się w stanie
„uruchamialny” – w szczególności przy braku innych wątków może się natychmiast rozpocząć wykonywać
![Page 17: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/17.jpg)
Metoda isAlive()
• public final boolean isAlive()• Zwraca true jeśli wątek wykonuje
swoje działanie, czyli czy wywołano już metodę start() a wątek jeszcze się nie zakończył, w przeciwnym przypadku zwraca false
![Page 18: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/18.jpg)
Stany wątków - uśmiercony• Zakończenie wykonania wątku następuje,
gdy:• metoda run() zakończy swoje działanie –
jest to preferowana metoda• wywołamy metodę destroy() (ale : nie
zwolnimy blokad obiektów)• wywołamy metodę stop() (niezalecana, ze
względu na możliwość rzucenia nieobsługiwalnego wyjątku
![Page 19: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/19.jpg)
Priorytety
• Jest to mechanizm wskazywania, który wątek jest ważniejszy i powinien być częściej wykonywany
• Nie mamy pewności co do kolejności wykonywania wątków
• Problemy z odwzorowaniem priorytetów w różnych systemach operacyjnych
![Page 20: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/20.jpg)
Priorytety
• public final void setPriority(int newPriority)
- ustawia nowy priorytet dla wątku
• public final int getPriority()- zwraca aktualną wartość priorytetu
![Page 21: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/21.jpg)
Priorytety
• Stałe służące do określania wartości priorytetu :
• public static final int MIN_PRIORITY- minimalna wartość priorytetu
• public static final int NORM_PRIORITY- domyślna wartość priorytetu
• public static final int MAX_PRIORITY- maksymalna wartość priorytetu
![Page 22: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/22.jpg)
import java.lang.Thread;
public class NumberThread extends Thread {
int myNumber;
public NumberThread( int theNumber ) {
myNumber = theNumber;
}
public void run() {
System.out.println("I'm "+ myNumber +
" in priority " + getPriority());
for(int i=0; i<25; i++)
System.out.println( "My Number Is " + myNumber + " in round : " + i);
}
}
public class ThreadDemo {
public static void main( String [] args ) {
NumberThread t1 = new NumberThread(1);
NumberThread t2 = new NumberThread(2);
t2.setPriority(2);
t2.start();
t1.setPriority(1);
t1.start();
}
}
![Page 23: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/23.jpg)
I'm 2 in priority 2
My Number Is 2 in round : 0
My Number Is 2 in round : 1
My Number Is 2 in round : 2
I'm 1 in priority 1
My Number Is 1 in round : 0
My Number Is 1 in round : 1
My Number Is 1 in round : 2
My Number Is 1 in round : 3
My Number Is 2 in round : 3
My Number Is 1 in round : 4
My Number Is 2 in round : 4
My Number Is 2 in round : 5
My Number Is 2 in round : 6
My Number Is 2 in round : 7
My Number Is 2 in round : 8
My Number Is 2 in round : 9
My Number Is 2 in round : 10
My Number Is 2 in round : 11
My Number Is 2 in round : 12
My Number Is 2 in round : 13
My Number Is 2 in round : 14
My Number Is 2 in round : 15
My Number Is 1 in round : 5
My Number Is 1 in round : 6
My Number Is 1 in round : 7
My Number Is 1 in round : 8
My Number Is 1 in round : 9
My Number Is 1 in round : 10
My Number Is 1 in round : 11
My Number Is 1 in round : 12
My Number Is 2 in round : 16
My Number Is 2 in round : 17
My Number Is 2 in round : 18
My Number Is 2 in round : 19
My Number Is 2 in round : 20
My Number Is 1 in round : 13
My Number Is 1 in round : 14
My Number Is 1 in round : 15
My Number Is 2 in round : 21
My Number Is 2 in round : 22
My Number Is 2 in round : 23
My Number Is 2 in round : 24
My Number Is 1 in round : 16
My Number Is 1 in round : 17
My Number Is 1 in round : 18
My Number Is 1 in round : 19
My Number Is 1 in round : 20
My Number Is 1 in round : 21
My Number Is 1 in round : 22
My Number Is 1 in round : 23
My Number Is 1 in round : 24
![Page 24: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/24.jpg)
Wątki straszą po nocach, czyli Demony
• Demony to specjalne rodzaje wątków
• Ich celem jest działanie w ”tle”
• Wirtualna maszyna kończy pracę, gdy zakończą się wszystkie wątki nie będące demonami
![Page 25: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/25.jpg)
Demony
• public final void setDaemon(boolean on)- aby wątek został demonem, należy wywołać tą metodę z parametrem
”true”- należy to zrobić przed wywołaniem
na rzecz tego wątku metody start()• public final boolean isDaemon()
- sprawdza, czy dany wątek jest demonem
![Page 26: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/26.jpg)
Synchronizacja wątków
• Aby lepiej zrozumieć czym jest synchronizacja, rozważmy program, którego zadaniem jest narysować linię wzdłuż przekątnej okna apletu
![Page 27: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/27.jpg)
import java.applet.*;
import java.awt.*;
public class Master extends Applet implements Runnable{
Thread thread1, thread2;
int [] tablicax;
int [] tablicay;
Graphics gdc;
int wskaznik;
public void init()
{
gdc = getGraphics();
thread1 = new Thread(this);
thread2 = new Thread(this);
thread1.start();
thread2.start();
tablicax = new int [100];
tablicay = new int [100];
}
public void paint(Graphics gdc){
for(int i=0;i<=wskaznik;i++)
gdc.fillRect(tablicax[i], tablicay[i],1,1);
}
public void run(){
for(int i=0;i<49;i++){
tablicax[wskaznik+1] = tablicax[wskaznik]+1;
System.out.print(
tablicax[wskaznik]+ " ");
wskaznik++;
System.out.print("-");
tablicay[wskaznik] =
tablicay[wskaznik-1]+1;
System.out.println(" " + tablicay[wskaznik-1] + " "+ wskaznik);
repaint();
}
}
}
![Page 28: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/28.jpg)
• A oto wynik działania naszego programu :
![Page 29: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/29.jpg)
Synchronizacja
• Aby uniknąć powyższej sytuacji, należy ograniczyć liczbę wątków mogących w danym momencie wykonywać pewien fragment kodu do jednego
• W tym celu należy zsynchronizować krytyczny fragment kodu
![Page 30: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/30.jpg)
Synchronizacja metody
• public synchronized void Counter()
{ ... }
• na czas wykonania metody synchronizowanej blokowana jest możliwość wywołania jakiejkolwiek innej metody synchronizowanej danego obiektu
![Page 31: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/31.jpg)
Synchronizacja bloku instrukcji
• synchronized (obiekt) blokInstrukcji
- na czas wykonywania blokuInstukcji dostęp do obiektu będzie zablokowany
- jeśli w momencie rozpoczęcia bloku instrukcji wyrażenie będzie już zablokowane, wątek się zawiesi w oczekiwaniu na odblokowanie
![Page 32: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/32.jpg)
Synchronizacja
Wywołanie :
• wskaznikNaObiekt.metodaSynchr(arg, ...);
jest równoważne wywołaniu:
• synchronized(wskaznikNaObiekt) {
wskaznikNaObiekt.metodaNieSyn(arg, ...);
}
![Page 33: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/33.jpg)
Zwalnianie blokady obiektu
• Blokada jest zawsze zwalniana na końcu synchronizowanego bloku, nawet gdyby w wyniku wyjątku, instrukcji break lub return sterowanie wątku zostało przeniesione poza synchronizowany blok
• Ważne jest aby w celu zawieszenia pracy wątku używać metody wait() gdyż na czas zawieszenia zwalnia ona blokadę obiektu
![Page 34: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/34.jpg)
Metoda wait()
• public final void wait()throws InterruptedException
• public final void wait(long timeout)throws InterruptedException
• public final void wait(long timeout, int nanos) throws InterruptedException
• Powoduje wstrzymanie pracy danego wątku aż zostanie wywołana metoda notify() lub notifyAll() lub upłynie czas podany jako argument
![Page 35: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/35.jpg)
Metoda wait()
• W przeciwieństwie do metody sleep() jest zwalniana blokada obiektu
• Wyjątek zostanie rzucony, gdy inny wątek wywoła metodę interrupt() na rzecz tego wątku
![Page 36: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/36.jpg)
Metody notify() i notifyAll()
• public final void notify()• public final void notifyAll()• Metoda notify() powoduje obudzenie
jednego, natomiast metoda notifyAll() wszystkich wątków zatrzymanych metodą wait()
![Page 37: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/37.jpg)
Metody wait(), notify(), notifyAll()
• Metody wait(), notify, notifyAll() muszą znajdować się wewnątrz synchronizowanego bloku lub metody.
• Jeśli zagnieździmy synchronizowane bloki lub metody, musimy pamiętać, że metody notify() i notifyAll() zwalniają blokadę tylko jednego obiektu, najbardziej wewnętrznego
![Page 38: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/38.jpg)
Uups, coś nie wyszło, czyli Zakleszczenia
• Gdy piszemy program używając mechanizmów synchronizacji, możemy doprowadzić do sytuacji, gdy w zestawie współdziałających wątków każdy wątek jest zawieszony lub dobrowolnie wstrzymany i nie istnieje możliwość odwieszenia ani uwolnienia jakiegokolwiek wątku
![Page 39: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/39.jpg)
Jak dochodzi do zakleszczeń
• Do zakleszczeń dochodzi, gdy jeden wątek, po założeniu blokady na pewien obiekt, próbuje uzyskać dostęp do innego obiektu, który jest blokowany przez drugi wątek, który próbuje uzyskać dostęp do obiektu zablokowanego przez pierwszy wątek
![Page 40: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/40.jpg)
Przykład zakleszczenia
• Program monitoruje pracę dwóch osób
• Każda osoba informuje o postępach swoich i konkurenta
![Page 41: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/41.jpg)
public class Worker implements Runnable {
private long counter = 0;
String name;
Worker other;
Worker (String name){
this.name = name;
}
Worker setOther(Worker other){
this.other = other;
return this;
}
synchronized void showStatus(){
Master.sendMessage(name + " " + counter + ", other: " + other.peep());
}
synchronized long peep(){
return counter;
}
public void run() {
while(true) {
counter++;
showStatus();
}
}
}
![Page 42: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/42.jpg)
import java.io.IOException;
public class Master {
static Worker tom, bob;
public static void main(String[] args)
throws IOException {
tom = new Worker("Tom");
bob = new Worker("Bob");
new Thread(tom.setOther(bob)).start();
new Thread(bob.setOther(tom)).start();
System.in.read();
}
static synchronized void sendMessage(String string){
System.out.println(string);
}
}
![Page 43: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/43.jpg)
I wynik działania programu:Tom 1, other: 0
Tom 2, other: 0
Tom 3, other: 0
Bob 1, other: 3
Bob 2, other: 3
Bob 3, other: 3
Bob 4, other: 3
Bob 5, other: 3
Bob 6, other: 3
Bob 7, other: 3
Bob 8, other: 3
Bob 9, other: 3
Tom 4, other: 10
![Page 44: Model współbieżności w Javie](https://reader036.vdocuments.pub/reader036/viewer/2022062409/5681488c550346895db5a412/html5/thumbnails/44.jpg)
Literatura
• Szkolenia firmy Sun na stronie https://learningcenter-sai.sun.com/
• Dokumentacja API http://java.sun.com/j2se/1.4.2/docs/api/
• http://www.google.pl
• Bruce Eckel „Thinking in Java”
• Jan Bielecki „Java od podstaw”