• Nie Znaleziono Wyników

Programowanie wielowątkowe

N/A
N/A
Protected

Academic year: 2021

Share "Programowanie wielowątkowe"

Copied!
35
0
0

Pełen tekst

(1)

Wykład 9:

(2)

Programowanie Równoległe

oparte na procesach:

wykonywalny program

własna przestrzeń adresowa

droga komunikacja i zmiana kontekstu

oparte na wątkach:

wątek to część programu

wspólna przestrzeń adresowa

(3)

Programowanie Równoległe w Javie

Oparte o wątki:

stany wątku: wykonywany, gotowy, zawieszony,

wznowiony, zablokowany

priorytety: wątek o wyższym priorytecie zawiesza ten

o niższym

synchronizacja: tylko jeden wątek wykonuje metodę

synchroniczną na danym obiekcie

(4)

Wątek Główny

tworzony automatycznie

wątek z którego powstają inne wątki

pierwszy powstaje, ostatni kończy się

Uzyskanie odwołania do bieżącego wątku:

(5)

Wątek Główny: Przykład

class CurrentThreadDemo {

public static void main(String args[]) { Thread t = Thread.currentThread();

System.out.println("Current thread: " + t); t.setName("My Thread");

System.out.println("After name change: " + t); try { for(int n = 5; n > 0; n--) { System.out.println(n); Thread.sleep(1000); } } catch (InterruptedException e) { System.out.println("Main interrupted"); } } }

(6)

Klasa Thread

Metody klasy

Thread

:

getName

– uzyskaj nazwę wątka

getPriority

– uzyskaj priorytet wątka

isAlive

– czy wątek działa?

join

– czekaj na zakończenie wątka

run

– wykonanie wątka

sleep

– zawieś wątek na jakiś czas

start

– wystartuj wątek

(7)

Tworzenie Nowego Wątka

przez implementację interfejsu

Runnable

przez dziedziczenie po klasie

Thread

Kiedy który?

wśród metod

Thread

, tylko

run()

musi być

przesłonięty

wybierz dziedziczenie po

Thread

, gdy inne metody

(8)

Tworzenie Nowego Wątka: Runnable

class NewThread implements Runnable {

Thread t;

NewThread() {

t = new Thread(this, "Demo Thread");

System.out.println("Child thread: " + t); t.start(); // Start the thread

}

public void run() { try {

for(int i = 5; i > 0; i--) {

System.out.println("Child Thread: " + i); Thread.sleep(500);

}

} catch (InterruptedException e) {

System.out.println("Child interrupted."); }

(9)

Tworzenie Nowego Wątka: Runnable

System.out.println("Exiting child thread."); }

}

class ThreadDemo {

public static void main(String args[]) { new NewThread(); // create a new thread try {

for(int i = 5; i > 0; i--) {

System.out.println("Main Thread: " + i); Thread.sleep(1000);

}

} catch (InterruptedException e) {

System.out.println("Main interrupted."); }

System.out.println("Main thread exiting."); }

(10)

Tworzenie Nowego Wątka: Thread

class NewThread extends Thread {

NewThread() {

super("Demo Thread");

System.out.println("Child thread: " + this); start(); // Start the thread

}

public void run() { try {

for(int i = 5; i > 0; i--) {

System.out.println("Child Thread: " + i); Thread.sleep(500);

}

} catch (InterruptedException e) {

System.out.println("Child interrupted."); }

(11)

Tworzenie Nowego Wątka: Thread

System.out.println("Exiting child thread."); }

}

class ExtendThread {

public static void main(String args[]) { new NewThread(); // create a new thread try {

for(int i = 5; i > 0; i--) {

System.out.println("Main Thread: " + i); Thread.sleep(1000);

}

} catch (InterruptedException e) {

System.out.println("Main interrupted."); }

System.out.println("Main thread exiting."); }

(12)

Wiele Wątków: Przykład 1

class NewThread implements Runnable { String name; // name of thread

Thread t;

NewThread(String threadname) { name = threadname;

t = new Thread(this, name);

System.out.println("New thread: " + t); t.start(); // Start the thread

(13)

Wiele Wątków: Przykład 2

// This is the entry point for thread. public void run() {

try { for(int i = 5; i > 0; i--) { System.out.println(name + ": " + i); Thread.sleep(1000); } } catch (InterruptedException e) { System.out.println(name + "Interrupted"); } System.out.println(name + " exiting."); } }

(14)

Wiele Wątków: Przykład 3

class MultiThreadDemo {

public static void main(String args[]) { new NewThread("One"); // start threads new NewThread("Two");

new NewThread("Three"); try {

// wait for other threads to end Thread.sleep(10000);

} catch (InterruptedException e) {

System.out.println("Main Interrupted"); }

System.out.println("Main thread exiting."); }

(15)

Zakończenie Wątku

Metoda zwraca true, jeśli wątek na której jest

wywołana wykonuje się:

final boolean isAlive()

Metoda czeka aż wątek na której wykonuje się

zakończy się:

(16)

Zakończenie Wątku: Przykład 1

class NewThread implements Runnable {

String name; // name of thread Thread t;

NewThread(String threadname) { name = threadname;

t = new Thread(this, name);

System.out.println("New thread: " + t); t.start(); // Start the thread

(17)

Zakończenie Wątku: Przykład 2

// This is the entry point for thread. public void run() {

try { for(int i = 5; i > 0; i--) { System.out.println(name + ": " + i); Thread.sleep(1000); } } catch (InterruptedException e) { System.out.println(name + " interrupted."); } System.out.println(name + " exiting."); } }

(18)

Zakończenie Wątku: Przykład 3

class DemoJoin {

public static void main(String args[]) { NewThread ob1 = new NewThread("One"); NewThread ob2 = new NewThread("Two"); NewThread ob3 = new NewThread("Three"); System.out.println(ob1.t.isAlive());

System.out.println(ob2.t.isAlive()); System.out.println(ob3.t.isAlive()); // wait for threads to finish

try { System.out.println("Waiting to finish."); ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch (InterruptedException e) { System.out.println("Main Interrupted"); }

(19)

Zakończenie Wątku: Przykład 3

System.out.println(ob1.t.isAlive()); System.out.println(ob2.t.isAlive()); System.out.println(ob3.t.isAlive());

System.out.println("Main thread exiting."); }

(20)

Priorytet Wątku

Decyduje kiedy wątek może się wykonywać.

W praktyce, czas CPU poświęcony dla wątku zależy od

szeregu innych czynników.

Ustalenie i sprawdzenie priorytetu:

final void setPriority(int level)

final int getPriority()

final int MIN_PRIORITY = 1

final int MAX_PRIORITY = 10

final int NORM_PRIORITY = 5

(21)

Priorytet Wątku: Przykład 1

class clicker implements Runnable { int click = 0;

Thread t;

Zapewnia że

running

jest sprawdzane w każdej

iteracji pętli, inaczej pętla może być optymalizowana.

(22)

Priorytet Wątku: Przykład 2

public clicker(int p) {

t = new Thread(this); t.setPriority(p);

}

public void run() {

while (running) { click++; } }

public void stop() { running = false; } public void start() { t.start(); }

(23)

Priorytet Wątku: Przykład 3

class HiLoPri {

public static void main(String args[]) { Thread.currentThread(). setPriority(Thread.MAX_PRIORITY); clicker hi = new clicker(Thread.NORM_PRIORITY+2); clicker lo = new clicker(Thread.NORM_PRIORITY – 2); lo.start(); hi.start(); try { Thread.sleep(10000); } catch (InterruptedException e) { System.out.println("Main interrupted."); }

(24)

Priorytet Wątku: Przykład 4

lo.stop();

hi.stop();

// Wait for child threads to terminate. try { hi.t.join(); lo.t.join(); } catch (InterruptedException e) { System.out.println( "InterruptedException caught"); } System.out.println("Low: " + lo.click); System.out.println("High: " + hi.click); } }

(25)

Synchronizacja Wątków

Kiedy kilka wątków korzysta z dzielonych zasobów.

Jak zapewnić aby tylko jeden wątek używał ten zasób.

Monitor: obiekt do którego może wejść jeden wątek.

Dwie metody:

użycie metod

synchronized

(26)

Metody Synchronized

Każdy obiekt ma związany z nim monitor.

Aby wejść do monitora, wywołaj jedną z metod

oznaczonych jako

synchronized

.

W tym czasie, wszystkie wątki muszą czekać aby

wykonać metodę

synchronized

na tym obiekcie.

Aby wyjść z monitora, wątek musi wyjść z metody

(27)

Metody Synchronized: Przykład 1

class Callme { void call(String msg) { System.out.print("[" + msg); try { Thread.sleep(1000); } catch(InterruptedException e) { System.out.println("Interrupted"); } System.out.println("]"); } }

(28)

Metody Synchronized: Przykład 2

class Caller implements Runnable {

String msg;

Callme target; Thread t;

public Caller(Callme targ, String s) { target = targ;

msg = s;

t = new Thread(this); t.start();

}

public void run() { target.call(msg); }

}

class Synch {

public static void main(String args[]) { Callme target = new Callme();

Caller ob1 = new Caller(target, "Hello"); Caller ob2 = new Caller(target,

"Synchronized");

Caller ob3 = new Caller(target, "World"); // wait for threads to end

try { ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch(InterruptedException e) { System.out.println("Interrupted"); } } }

(29)

Metody Synchronized: Przykład 3

public static void main(String args[]) { Callme target = new Callme();

Caller ob1 = new Caller(target, "Hello"); Caller ob2 = new Caller(target, "Synch");

Caller ob3 = new Caller(target, "World"); // wait for threads to end

try { ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch(InterruptedException e) { System.out.println("Interrupted"); } } }

(30)

Metody Synchronized

Trzy wywołania metody call przeplatają się w czasie.

Należy zapewnić serializację wykonania call:

class CallMe {

synchronized void call(Sting msg) { ...

} }

To zapobiegnie aby inne wątki wykonywały metodę

(31)

Instrukcja Synchronized

Synchronizacja dostępu do klasy która nie była

zaprojektowana dla wielo-wątkowości.

synchronized(object) { ...

}

Zapewnia że wywołanie metody składowej obiektu

(32)

Instrukcja Synchronized: Przykład 1

class Callme { void call(String msg) { System.out.print("[" + msg); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Interrupted"); } System.out.println("]"); } }

(33)

Instrukcja Synchronized: Przykład 2

class Caller implements Runnable {

String msg;

Callme target; Thread t;

public Caller(Callme targ, String s) { target = targ;

msg = s;

t = new Thread(this); t.start();

}

public void run() {

synchronized(target) { target.call(msg);

} } }

(34)

Instrukcja Synchronized: Przykład 3

class Synch1 {

public static void main(String args[]) { Callme target = new Callme();

Caller ob1 = new Caller(target, "Hello"); Caller ob2 = new Caller(target, "Synch"); Caller ob3 = new Caller(target, "World"); // wait for threads to end

try { ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch(InterruptedException e) { System.out.println("Interrupted"); } } }

(35)

Instrukcja Synchronized: Przykład 3

String msg;

Callme target; Thread t;

public Caller(Callme targ, String s) { target = targ;

msg = s;

t = new Thread(this); t.start();

}

// synchronize calls to call() public void run() {

synchronized(target) { // synchronized block target.call(msg);

} } }

class Synch1 {

public static void main(String args[]) { Callme target = new Callme();

Caller ob1 = new Caller(target, "Hello"); Caller ob2 = new Caller(target,

"Synchronized");

Caller ob3 = new Caller(target, "World"); // wait for threads to end

try { ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch(InterruptedException e) { System.out.println("Interrupted"); } } }

Cytaty

Powiązane dokumenty

 jeśli w przypisach powołuje się wyłącznie na jedną pozycję danego autora, to przy drugim i następnych powołaniach się na daną publikację można stosować zapis

Kiedy wydaje się, że już takie znalazł, okazuje się, że rzeczywistość nie jest tak kolo- rowa, jak mu się to wydawało.. Po tym odkryciu lisek zaczyna bardzo tęsknić za

NIP Nr Tel. Upoważniam firmę Ernst & Young Academy of Business sp. do wystawienia faktury VAT bez podpisu odbiorcy. - Na tydzień przed szkoleniem otrzymają Państwo

Nagroda za pisanie w niewłaściwej sali jest równa -10 punktów (odejmuję 10 punktów od

Przenoszenie zakażenia COVID-19 z matki na dziecko rzadkie Wieczna zmarzlina może zacząć uwalniać cieplarniane gazy Ćwiczenia fizyczne pomocne w leczeniu efektów długiego

[r]

Ten przykład to ilustracja szerszego zjawiska, jakim jest kurczenie się oferty publicznej ochrony zdrowia i poszerzanie prywatnej.. Jest to

Według ekspertów Unii Owocowej, rok 2021 dla producentów owoców i warzyw, będzie kolejnym rokiem poświęconym zdobywaniu nowych rynków i prezentowaniu polskich owoców na