Presentation is loading. Please wait.

Presentation is loading. Please wait.

Procesare paralela in Java

Similar presentations


Presentation on theme: "Procesare paralela in Java"— Presentation transcript:

1 Procesare paralela in Java
12/1/2017 Curs 8 Procesare paralela in Java

2 Arhitecturi Paralele

3 Clasificare arhitecturi paralele
Clasificarea Flyn SISD - conventional SIMD - calcul vectorial MISD - scalcul sistolic MIMD – cazul general

4 SISD : Von Neuman Instructiuni Procesor Date Intrare Date Iesire

5 Arhitectura MISD B C A Flux de date de Iesire Flux de date de Intrare
Instructiuni A Flux de date de Iesire Procesor A B C Instructiuni B Flux de Instructiuni C Flux de date de Intrare

6 Architectura SIMD Ci<= Ai * Bi A B C Flux de Instructiuni Flux de
Procesor A B C Date de Intrare A Flux de Date de Iesire A Flux de Date de Iesire B Flux de Date de Intrare B Flux de Date de Iesire C Flux de Date de Intrare C Ci<= Ai * Bi

7 Architectura MIMD A B C Flux de Instructiuni A Flux de Instructiuni B
Instructiuni C Flux de Date de Iesire A Flux de Date de Intrare A Procesor A Flux de Date de Iesire B Flux de Date de Intrare B Procesor B Flux de Date de Iesire C Flux de Date de Intrare C Procesor C

8 Masina MIMD cu memorie comuna
Procesor A Procesor B Procesor C MEMORIE MAGISTRALA MEMORIE MAGISTRALA MEMORIE MAGISTRALA Sistem de Memorie Globala

9 MIMD cu memorie distribuita
Canal Comunicatie Canal Comunicatie Procesor A Procesor B Procesor C MEMORIE MAGISTRALA MEMORIE MAGISTRALA MEMORIE MAGISTRALA Memorie Sistem A Memorie Sistem B Memorie Sistem C

10 Nivele de paralelism

11 Nivele de Paralelism Granularitate cod Entitate Cod Granularitate mare
(nivel task) Program Granularitate medie (nivel control) Functie (thread) Granularitate fina (nivel date) Bucla Granularitate foarte fina (alegeri multiple ) Cu suport hard Task i-l Task i Task i+1 func1 ( ) { .... } func2 ( ) { .... } func3 ( ) { .... } a ( 0 ) =.. b ( 0 ) =.. a ( 1 )=.. b ( 1 )=.. a ( 2 )=.. b ( 2 )=.. + x Load

12 Paralelism la nivel de procese

13 Procesul clasic Memorie comuna Mentinuta de kernel procese processe
Stiva Stiva Memorie COMUNA, segmente, pipes, Fisiere deschise sau mapate in memorie Date Date Text Text Memorie comuna Mentinuta de kernel procese processe

14 Definirea/Instantierea unor procese Exemple de relatii de precedenta

15 Procese cu unul sau mai multe fire interne de executie
Proces cu un singur fir de executie Proces cu mai multe fire de executie Fire de executie Thread-uri Flux unic de instructiuni Spatiu de adrese COMUN pt fire Al procesului Flux multiplu de instructiuni

16 Thread-uri

17 Ce sunt firele de executie?
Un fir de executie este o portiune de cod executabil care se poate executa in paralel (concurent) cu alte fire de executie) Registri Context Hardware/ software Cuvant stare Program Counter executare

18 Thread light (“proces usor”)
STIVA FIRULUI Memorie Comuna DATELE FIRULUI TEXTUL FIRULUI Thread light (“proces usor”) Un fir de executie peste o zona mica continua de memorie care este primit de la (si din) procesul parinte

19 Exemplu Thread in Linux
void *func ( ) { /* define local data */ /* function code */ thr_exit(exit_value); } main ( ) thread_t tid; int exit_value; thread_create (0, 0, func (), NULL, &tid); thread_join (tid, 0, &exit_value);

20 Paralelism in procese Date a b r1 c d r2
int add (int a, int b, int & result) // corpul int sub(int a, int b, int & result) Date Procesor a b r1 c d r2 IS1 add pthread t1, t2; pthread-create(&t1, add, a,b, & r1); pthread-create(&t2, sub, c,d, & r2); pthread-par (2, t1, t2); Processor IS2 sub

21 Paralelism date do “ dn/2 dn2/+1 dn sort( int *array, int count)
//...... Procesor do dn/2 dn2/+1 dn Sortare pthread-t, thread1, thread2; pthread-create(& thread1, sort, array, N/2); pthread-create(& thread2, sort, array, N/2); pthread-par(2, thread1, thread2); IS Procesor Sortare

22 De ce thread-uri? Proces cu un singur fir de executie: apeluri blocante, executie secventiala Cu automat finit (bazat pe eveniment) apeluri neblocante si paralelism

23 Sistem de operare

24 Thread-uri utilizator
12/1/2017 Thread-uri utilizator Thread-urile sunt gestionate de o biblioteca de thread-uri

25 Thread-uri la nivel kernel
12/1/2017 Kernel-ul este constient de existenta thread-uri

26 Procese “usoare” (Light-weight-LWP)
12/1/2017 Procese “usoare” (Light-weight-LWP) Presupun maparea maparea mai multor LWP peste un proces real (greu - heavy-weight)

27 (UNIX, VMS, MVS, NT, OS/2 etc.)
Sisteme Multitasking Proces Spatiu Utilizator Kernel Structura Procesului UNIX Hardware (UNIX, VMS, MVS, NT, OS/2 etc.)

28 Sisteme Multitasking Procese P1 P2 P3 P4 kernel Hardware
Fiecare proces este independent kernel Hardware

29 Procese Multithread T1’s SP T3’sPC T1’sPC T2’sPC T1’s SP Cod
Utilizator Date globale T2’s SP Structura Procesului Kernel

30 Maparea thread-urilor
1:1 DEC, NT, OS/1, AIX. IRIX M:1 HP-UNIX M:M 2-level

31 Modelul pe doua nivele al SunOS
Proces Traditional Proc 1 Proc 2 Proc 3 Proc 4 Proc 5 Utilizator LWP-uri Thread-uri Kernel Kernel Hardware Procesoare

32 Paralelism la nivel de thread-uri

33 Multithreading – Mono procesor
Concureta Vs Paralelism Concurenta P1 CPU P2 P3 timp

34 Multithreading - Multiprocesor
Concurenta Vs Paralelism CPU P1 CPU P2 CPU P3 timp

35 Thread-uri la nivel user
Model de lucru Thread-uri la nivel user Procesoare virtuale Procesoare fizice Planificare nivel user (User) Planificare nivel Kernel (Kernel)

36 Architectura generala a modelului bazat pe thread-uri
Ascunde detaliile arhitecturii masinii Mapeaza thread-urile user peste cele native ale kernel Memoria procesului parinte este vazuta in comun de thread-uri

37 Modele de programare folosind thread-uri
1. master/slave Peer 3. pipeline

38 Modelul master slave Resurse Program sclavi Fisiere Baze Date Stapan
taskX Baze Date Stapan taskY main ( ) Input (Stream) Disc-uri taskZ Dispozitive Speciale

39 Modelul peer Resurse Input (static) Program Sclavi Fisiere Baze Date
12/1/2017 Program Resurse Sclavi Input (static) Fisiere taskX Baze Date taskY Disc-uri taskZ Dispozitive Speciale

40 Pipeline de thread-uri
Program Filtru Thread-uri Nivel 1 Nivel 2 Nivel 3 Input (Stream) Fisiere Baze date Disc-uri Dispozitive Speciale Fisiere Baze date Disc-uri Dispozitive Speciale Fisiere Baze date Disc-uri Dispozitive Speciale Resurse

41 Observatii privind utilizarea thread-urilor
Daca toate operatiile sunt cu mai consumatoare de procesor nu este recomandat sa se lucreze pe thread-uri Desi crearea este simpla totusi foloseste ea insasi niste resurse Thread-urile prea simple (5 linii) nu sunt eficiente

42 Detalii fire de executie

43 Cai de creare a unui thread in Java
class MyThread extends Thread { public void run() // corpul thread ce trebuie executat } MyThread thr1 = new MyThread(); thr1.start();

44 Se creaza o clasa care implementeaza interfata Runnable
class ClassName implements Runnable { ..... public void run() // corpul thread ce trebuie executat } ClassName myObject = new ClassName(); Thread thr1 = new Thread( myObject ); thr1.start();

45 Exemplul 2 class ThreadDemo implements Runnable { ThreadDemo()
{Thread ct = Thread.currentThread(); System.out.println("Current Thread: "+ct); Thread t = new Thread(this,"Demo Thread"); t.start(); try { Thread.sleep(3000); } catch(InterruptedException e) { System.out.println("Interrupted."); } System.out.println("Exiting mainthread."); }

46 public void run() { try { for(int i=5; i>0; i--) { System.out.println(" " + i); Thread.sleep(1000); } } catch(InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); public static void main(String args[]) new ThreadDemo();

47 Gestiunea thread-ului curent
class CurrentThreadDemo { public static void main(String arg[]) { Thread ct = Thread.currentThread(); ct.setName( "My Thread" ); System.out.println("Current Thread : "+ct); try { for(int i=5; i>0; i--) { System.out.println(" " + i); Thread.sleep(1000); }

48 Current Thread : Thread[My Thread,5,main]
catch(InterruptedException e) { System.out.println("Interrupted.") } Run: Current Thread : Thread[My Thread,5,main] 5 4 3 2 1

49 Ciclul de viata al unui thread

50 Runnable Thread-ul este lansat în execuţie prin apelul metodei start() din clasa Thread.
Not Runnable - se poate ajunge în această stare dacă:

51 Dead În această stare se ajunge când firul şi-a terminat execuţia. Metoda isAlive() returnează: true, dacă firul de execuţie a fost pornit şi nu a fost oprit (este în starea Runnable sau Not Runnable) false, dacă firul de execuţie este fie în starea New Thread, fie în starea Dead.

52 Cazurile în care un fir de execuţie poate ajunge din starea Not Runnable în starea Runnable
Dacă a fost apelată metoda sleep(), atunci firul execuţie ajunge în starea Runnable după scurgerea intervalului de timp specificat. Dacă a fost apelată metoda wait(), atunci un alt fir de execuţie trebuie să-l informeze dacă acea condiţie este îndeplinită sau nu (folosind metodele notify() şi notifyAll() din clasa Object).

53 Oprirea temporară a unui fir de execuţie
public static void sleep(long millis) throws InterruptedException public static void sleep(long millis,int nanos) throws InterruptedException De exemplu: try { // se face o pauza de o secunda Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace();}

54 Terminarea unui fir de execuţie
Pentru ca un fir de execuţie să se termine trebuie ca metoda run() să-şi termine execuţia. Există două metode pentru terminarea unui fir de execuţie: Metoda run() îşi termină execuţia în mod natural: dacă avem instrucţiuni cu timp de execuţie finit Daca avem bucle finite.

55 Fire de execuţie de tip „daemon”
Un „daemon” reprezintă un fir de execuţie care se termină automat la terminarea aplicaţiei. De obicei firele „daemon” pun la dispoziţia celorlalte fire de execuţie anumite servicii.

56 Proceselor/firelor de executie
Planificarea Proceselor/firelor de executie

57 Alternarea seventelor de calcul cu rafalele (“burst”) de instructiuni de intrare iesire

58 Planificatorul CPU Selecteaza dintre procesele active in memorie pe cele care sunt gata a fi executate si rezerva procesorul pentru unul din ele (secvential pur) Deciziile de planificare pot aparea atunci cand un proces: 1. Trece din starea de executie in starea de asteptare 2. Trece din starea de executie in starea de gata de executie 3. Trece din starea de asteptare in starea de gata de executie 4. Se termina

59 Distribuitorul/Selectorul de procese - Dispatcher
Acest modul da controlul procesorului catre procesul selectat de catre planificatorul pe termen scurt si implica Schimbarea contextului Trecerea in mod utilizator Saltul catre locatia corespunzatoare din programul utilizatorului pentru a-l reporni Intarzierea selectorului – timpul necesar acestuia pentrua a opri un proces si a-l porni pe urmatorul

60 Criterii pentru realizarea planificarii
Utilizarea procesor  Max Incarcare - Throughput –  Max Turnaround time – Min Timp de asteptare – Min Timp de raspuns – )  Min

61 Planificare de tip primul venit primul servit (FCFS)
Proces Timp operatii i/o P1 24 P2 3 P3 3 Sa presupunem ca procesele ajung in urmatoarea ordine: P1 , P2 , P3 Atunci diagrama Gantt pentru planificare este: P1 P2 P3 24 27 30

62 FCFS Dca procesele ajung in ordinea P2 , P3 , P1 atunci vom avea urmatoarea diagrama Gatt a planificarii lor P1 P3 P2 6 3 30

63 Cea mai scurta sarcina este prima (SJF)
Se asociaza fiecarui process lungimea urmatorului set de operatii de I/O care il va efectua (CPU burst). Aceste lungimi sunt folosite pentru a planifica procesul cu cel mai scurt timp Exista doua abordari: Nepreemptiva preemptiva

64 Exemplu de SJF nepreemptiv
Proces Timp sosire Timp operatii I/O P P P P SJF (non-preemptiv) P1 P3 P2 7 3 16 P4 8 12

65 Exemplu de SJF preemptiv
Proces Timp de aparitie Timp pentru i/o P P P P SJF (preemptiv) P1 P3 P2 4 2 11 P4 5 7 16

66 Planificare bazata pe prioritati
Un numar al prioritatii este asociat la fiecare proces Procesorul va fi dat procesului cu prioritatea cea mai mare (adica cel mai mic numar). Si in acest caz procesul de planificare poate fi: Preemptiv nepreemptiv Problema  Starvation Solutie  Aging

67 Round Robin (RR) Fiecare proces primeste o mica unitate din timpul procesorului (cuanta de timp – time quantum), de obicei durata acesteia este intre 10 si 100 milliseconde. Daca exista n procese in aceasta coada si cuanta de timp este q, atunci fiecare proces va avea acces la 1/n din timpul procesorului in bucati de cel mult q unitati de timp o data. Rezulta ca nici un proces nu va astepta mai mult de (n-1)q unitati de timp. Performanta q este mare  FIFO q este mica  q trebuie sa fie mare tinand insa cont de comutarea contextului altfel supraincarcarea obtinuta va fi prea mare

68 Exemplu de RR cu cuanta de 20
Proces Timp pentru i/o P1 53 P2 17 P3 68 P4 24 Diagrama Gantt asociata va fi: P1 P2 P3 P4 20 37 57 77 97 117 121 134 154 162

69 Cuanta de timp si timpul de de comutare a contextului

70 Timpul de executie a unui proces variaza functie de cuanta de timp

71 Cozi multinivel Coada “gata de executie” este formata din doua cozi separate foreground – interactiva background – fundal (batch) Fiecare coada are propriul ei algoritm de planificare foreground – RR background – FCFS Planificarea trebuie realizata intre cozi Planificare cu prioritate fixa Cu cuante de timp

72 Planificarea cozilor multinivel

73 Coada de raspuns (feedback) multinivel
Un proces poate fi mutat ntre cozi diferite (de exemplu “imbatranirea” poate fi implenentata in aceasta maniera Un planificator pentru coada de raspuns multinivel (multilevel-feedback-queue) este definit de utmatorii parametri Numarul cozilor Algoritmi de planificare pentru fiecare coada Metodele folosite pentru a determina cand se creste prioritatea unui proces Metodele folosite pentru a determina cand se scade prioritatea unui proces Metodele folosite pentru a determina in care coada va intra un proces care trebuie tratat

74 Exemplu de coada de raspuns multinivel
Fie trei cozi: Q0 – cu cuanta de timp 8 milisecunde Q1 – cu cuanta de timp de 16 milisecunde Q2 – FCFS

75 Planificarea in Linux Se folosesc doi algoritmi Time-sharing Real-time
Bazat pe prioritati de credit (Prioritized credit-based) – Creditul este scazut atunci cand apare o intrerupere de timp Cand creditul = 0, se alege alt proces Cand toate procesele au creditul = 0, se reincepe procesul de creditare Real-time Soft real-time Daca este conform standardului Posix.1b vom avea doua categorii FCFS si RR Procesul cu cea mai mare prioritate este primul executat

76 Planificarea thread-urilor
Locala atunci cand ninlioteca de thread-uri va decide Globala atunci cand decide kernel-ul

77 Planificarea thread-urilor in Java
JVM foloseste o politica de planificarea preemptiva bazata pe prioritati JVM va planifica un thread spre executare atunci cand: Thread-ul care este in executie curenta va parasi starea Runnable Un thread cu o prioritate mai mare intra in starea Runnable

78 Time-Slicing Deoarece planificarea pe cuante nu este asigurata de JVM trebuie folosita metoda yield() while (true) { // fa un calcul intensiv computational . . . Thread.yield(); }

79 Prioritatile thread-urilor
Prioritate tip Thread.MIN_PRIORITY prioritate minima Thread.MAX_PRIORITY prioritate maxima Thread.NORM_PRIORITY prioritate implicita Prioritatile pot fi schimbate folosind metoda setPriority() De ex setPriority(Thread.NORM_PRIORITY + 2);

80 Exemplu Prioritati thread
class Clicker implements Runnable { int click = 0; private Thread t; private boolean running = true; public Clicker(int p) { t = new Thread(this); t.setPriority(p); } public void run() { while(running) click++; } public void start() { t.start(); } public void stop() { running = false; }

81 Exemplu Prioritati thread
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 (Exception e) { }

82 Lo. stop(); Hi. stop(); System. out. println(Lo. click + " vs. " + Hi
Lo.stop(); Hi.stop(); System.out.println(Lo.click + " vs. " + Hi.click); } Run1: (on Solaris) 0 vs Run2: (Window 95) vs

83 Problema inversiunii prioritatilor in cazul sincronizarii
Fie un proces L de prioritate scazuta si un proces H de prioritate crescuta. Ambele au acces la o resursa comuna unica (adica se permite numai acces mutual exclusiv)

84 Solutia pentru inversia prioritatii
Protocol de mostenire a prioritatilor Daca thread-ul t1 incearca sa achizitioneze un lock care este detinut de un thread de prioritate scazuta t2, atunci se va creste temporar prioritatea lui t2 la nivelul celei detinute de t1 in timpul in care t2 mentine lock-ul Protocol cu simularea limitarii prioritatii (Highest locker) Unui monitor I se da o prioritate atunci cand este creat. Aceasta este cea mai mare prioritate pe care un thread care incearca sa intre in zona monitorizata o poate avea O data ce thread-ul intra in zona sincronizata prioritatea lui este crescuta la cea a monitorului.

85 Coerenta datelor Ce facem daca mai multi vor sa scrie simultan aceasi valoare? Cea mai simpla solutie:excluziunea mutuala

86 Variabile pentru sincronizare in memoria comuna
Proces 1 Proces 2 Variabila pentru sinchronizare Memorie Comuna S S S S Thread

87 Lock Definitie O entitate care poate fi detinuta de un singur thread la un moment dat Proprietati Reprezinta o forma/tip de sincronizare Este folosita pentru a intari/realiza excluziunea mutuala Thread-urile pot achizitiona/elibera un lock

88 Obiecte sincronizate in Java
TOATE obiectele java furnizeaza (pt ca detin) un lock Se aplica cuvantul cheie synchronized asupra obiect Se obtine excluziunea mutuala pentru secventa din bloc Exemplu Object x = new Object(); void foo() { synchronized(x) { ... } bloc

89 Metode sincronizate in Java
Si metodele Java furnizeaza lock-uri Se aplica cuvantul cheie synchronized la metoda Se sincronizeaza pe un obiect (implicit) apeland metoda Example synchronized void foo() { …cod… } // este echivalenta cu void foo() { synchronized (this) { …cod… } } bloc

90 Sincronizarea accesului la campuri “mutable”
12/1/2017 Sincronizarea accesului la campuri “mutable” Acestea sunt de fapt camputile care permit modificarea continutului. Intr-un mediu parallel ( multi thread) accesarea unei variabile commune necesita coordonare explicita intre cei care scri si cei care citesc datorita problemei coerentei datelor. Procesul de coordonare in acest caz se numeste sincronizare.

91 12/1/2017 Exemplu import java.util.Date; public final class MutablePlanet { public MutablePlanet(int aId, String aName, Date aDateOfDiscovery) fId = aId; fName = aName; fDateOfDiscovery = new Date(aDateOfDiscovery.getTime()); }

92 12/1/2017 public synchronized int getId() {return fId;} public synchronized void setId(int aNewId) { fId = aNewId; } public synchronized String getName() { return fName; } public synchronized void setName(String aNewName) { fName = aNewName; } public synchronized Date getDateOfDiscovery() { return new Date(fDateOfDiscovery.getTime()); } public synchronized void setDateOfDiscovery( Date aNewDiscoveryDate) { fDateOfDiscovery.setTime(aNewDiscoveryDate.getTime()); }

93 12/1/2017 private int fId; private String fName; private Date fDateOfDiscovery; // }

94 Indicatii pentru crearea unei clase imutabila
12/1/2017 Indicatii pentru crearea unei clase imutabila Asigurati ca clasa nu poate fi suprascrisa folosind final sau fabric static impreuna cu constructori private Campurile clasei trebuie sa fie private si final Nu furnizati nici o metoda care poate schimba starea unui obiect in nici un fel (nu nu mai setere si getere nimic)

95 Exemplu import java.util.Date; public final class Planet {
12/1/2017 Exemplu import java.util.Date; public final class Planet { public Planet (double aMass, String aName, Date aDateOfDiscovery) fMass = aMass; fName = aName; fDateOfDiscovery = new Date(aDateOfDiscovery.getTime()); } public double getMass() { return fMass;

96 12/1/2017 public String getName() { return fName; } // public Date getDateOfDiscovery() { //not ok // return fDateOfDiscovery; // } public Date getDateOfDiscovery() {//ok return new Date(fDateOfDiscovery.getTime()); private final double fMass; private final String fName; private final Date fDateOfDiscovery;

97 12/1/2017 Lock In cazul lock-ului intrinsec operatiunea de lock va fi efectuata automat de catre Java (in spatele scenei). Utilizarea synchronized este asociata cu doua tipuri de lock intrinsec Un “lock pe instanta” care este atasat unui singur obiect Un “lock static” atasata unei clase

98 12/1/2017 In mod similar preluare controlului unui lock static va impedica celelalte thread-uri sa apeleze o metoda sincronizata static DANU NU va bloca apelul metodelor nesincronizate sau a instantelor de metoda sincronizate Lock-ul static poate fi obtinut in afara header-ului metodei in doua moduri synchronized(Blah.class),folosind clasa literal synchronized(this.getClass()), daca un obiect este disponibil

99 Exista doua categorii de operatii asupra unui obiect:
Cu apel unic: Cu apel multiplu Exista mai multe situatii care trebuie analizate pentru a decide utilizarea lock-ului lock-never apelantul nu are nevoie nici o data sa obtina un lock extern inainte de a efectua orice tip de operatie.

100 lock-always – apelantul are nevoie intotdeauna sa obtina un lock extern inainte de efectuarea oricarei operatii. lock-sometimes – apelantul are nevoie cate o data sa obtina un lock extern inainte de a fectua unele operatii. Instantele sunt mutable iar implementarea clasei efectuare intern majoritatea sincronizarilor. lock-hostile – operatiile nu pot fi effectuate correct (safe) intr-un mediu multi-thread chiar daca se obtine tot tipul lock-ul extern.

101 Sincronizarea la nivel de sectiuni
Controlul executiei

102 Hazard de curse - Data Race
x = y = 0 Thread 1 Thread-urile pornesc Thread 2 x = 1 y = 1 j = y i = x Se poate sa avem ca rezultat i = 0 and j = 0?

103 Raspuns: DA! x = y = 0 Thread 1 Thread 2 Thread-urile pornesc x = 1
j = y i = x

104 Cum se poate intampla asa ceva?
Compilatorul poate reordona instructiunile Sau sa mentina variabilele in registri Procesorul le poate reordona Modelul de memorie folosit este proiectat sa suporte otimizari agresive (cu relaxarea conditiilor) Poate include optimizari neimplementate in general

105 Sincronizarea Se foloseste cand
Trebuie delimitat un bloc care trebuie sa aiba executie atomica (neintrerupta) de alt thread Introduce un punct de sincronizare a informatiei/comunicatiei intre thread-uri Obs Implica totusi o supraincarcare (mica) in timpul executiei.

106 Exemplu de operatiune neatomica
public class OperNeAtomica implements Runnable { static int x = 0; public void run() { int tmp = x; x = tmp+1; } public static void main(String[] args) for (int i = 0; i < 3; i++) new Thread(new OperNeAtomica ()).start(); System.out.println(x); }

107 Probleme la sincronizare
Utilizarea acelasi lock pentru a furniza excluderea mutuala Asigurarea tranzactiilor atomice Evitarea deadlock=ului

108 Utilizarea acelasi lock
Lock comun Lock separat Exemplu void run() { Object o = new Object(); // diferit pentru fiecare thread synchronized(o) { … // sunt sanse sa apara data race }

109 Tranzactie atomica Problema potentiala Exemplu synchronized(lock) {
int tmp = x; x = tmp; }

110 Utillizarea sincronizarii
public class OperNeAtomica implements Runnable { static int x = 0; static Object lock = new Object(); public void run() { int tmp; synchronized(lock) { tmp = x; }; synchronized(lock) { x = tmp+1; } }

111 Evitarea blocajului reciproc
In general este bine a se evita executia unor operatii consumatoare de timp intr-o zona de lock (cand se mentine controlul acestuia) Ce poate dura? Diverse… Aparitia altui lock Poate aparea blocaj reciproc (deadlock)

112 Exemplu Deadlock Thread1() { synchronized(a) synchronized(b) … ceva }

113 Exemplul 2 de deadlock void moveMoney(Account a, Account b, int amount) {synchronized(a) {synchronized(b) { a.debit(amount); b.credit(amount); } Thread1() { moveMoney(a,b,10); } Thread2() { moveMoney(b,a,100); }

114 Abstract Data Type – Buffer

115 Implementare Buffer public class Buffer {
private LinkedList objects = new LinkedList(); public synchronized add( Object x ) { objects.add(x); } public synchronized Object remove() { while (objects.isEmpty()) { ; return objects.removeFirst();

116 Eliminare Deadlock public class Buffer { private Object [] myObjects;
private int numberObjects = 0; public synchronized add( Object x ) { objects.add(x); } public Object remove() { while (true) { synchronize(this) { if (!objects.isEmpty()) { return objects.removeFirst(); } }

117 Metodele Wait & Notify wait() Apelata de un obiect notifyAll()

118 Utilizarea Wait si NotifyAll
public class Buffer { private LinkedList objects = new LinkedList(); public synchronized add( Object x ) { objects.add(x); this.notifyAll(); } public synchronized Object remove() { while (objects.isEmpty()) { this.wait(); } return objects.removeFirst();

119 Codul devine public class Buffer
{ private LinkedList objects = new LinkedList(); public synchronized add( Object x ) {objects.add(x); this.notifyAll(); } public synchronized Object remove() { while (objects.isEmpty()) { try { this.wait(); } catch (InterruptedException e) {} } return objects.removeFirst();

120 Ce este un thread pool O colectie de thread-uri care sunt create simultan ( de exemplu cand un server porneste) NU este necesar ca serverul sa reeze cate un thread pe masura ce cererile de la clienti apar IN loc serverul poate folosi un thread care a fost deja creat si care fie este liber fie se va elibera in curand

121 De ce avem nevoie de thread pools
Imbunatatesc utilizarea resurselor atentie crearea unui nou thread induce totusi o suprancarcare care nu poate neglijata Folosirea lor permite aplicatiilor sa isi controleze complet utilizarea thread-urilor interne

122 Utilizarea in servere Thread pools sunt importante in psecial pentru aplicatiile de tip client server Deoarece procesarea fiecarui task individual dureaza putin iasr numarul de cereri este mare Serverele nu trebuie sa consume mai mult timp si resurse pentru crearea si distrugerea thread-urilor decat pentru deservirea clientilor

123 Implementarea evidenta
12/1/2017 Implementarea evidenta Fie un pool de thread Fiecare task cere la pornire un thread si il returneaza pool-ului dupa ce si-a terminat treaba Care este problema aici Modelul “Synchronized” - clientul asteapta pana cand serverul ii satisface cererile

124 Implementarea evidenta …. nu e cea mai buna
Cand pool-ul este gol threadu-l emitent de job trebuie sa astepte ca un thread sa fie disponibil De obicei se doreste evitarea blocarii acestui thread Un server ar putea dori sa efectueze unele actiuni cand vin prea multe cereri

125 Toate thread-urile worker asteapta pentru a primi treaba
O solutie posibila Fiecare thread se uita dupa cereri (tasks) in coada wait() Coada Task-uri Thread-uri worker Daca Q este gol Toate thread-urile worker asteapta pentru a primi treaba

126 O solutie posibila Task Coada Task-uri Thread-uri worker
Model “A-synchronized” “Lanseaza si uita ” Numarul de thread-uri worker este Fix. Atunci cand un task este introdus in coada Este apelat un notify

127 O solutie posibila Task Coada Task-uri Thread-uri Worker
notify() Task Coada Task-uri Thread-uri Worker Numarul de thread-uri este fix Atunci cand un task este inserat In coada va fi apelat notify

128 Thread Pool Implementation
public class TaskManager { LinkedList taskQueue = new LinkedList(); List threads = new LinkedList(); public TaskManager(int numThreads) {for(int i=0; i<numThreads; ++i) {Thread worker = new Worker(taskQueue); threads.add(worker); worker.start(); } public void execute(Runnable task) {synchronized(taskQueue) { taskQueue.addLast(task); taskQueue.notify(); }

129 Thread Pool Implementation
public class Worker extends Thread { LinkedList taskQueue = null; public Worker(LinkedList queue) { taskQueue = queue; } public void run() { Runnable task = null; while (true) { synchronized (taskQueue) { while (taskQueue.isEmpty()) { try {taskQueue.wait();} catch (InterruptedException ignored) {} } task = (Runnable) taskQueue.removeFirst(); task.run();

130 Riscuri in folosirea Thread Pools
Thread-urile pot avea scapari Sa se blocheze astepand terminarea unei operatii de i/o De exemplu clientul poate oprin interactiunea cu un socket fara a-l inchide corespunzator

131 Dimensiunea pool-ului
Fiecare thread consuma resurse: memore, efort pentru management etc. Un pool mare poate conduce la infometare Task-urile care vin asteapta un thread liber

132 Tratarea a unui numar prea mare de cereri la un server multithtread
Nu se adauga la coada de procesare toate cererile (se ignora sau se trimite un mesaj de eroare) Se folosesc cateva dimensiuni predefinite pentru pool conform tipului de incarcare al serverului ( dar ete bine ca sa nu schimbam prea des dimensiunea pool-ului)

133 Calculul dimensiunii pool
Telul principale este: ca procesarea sa continue chiar daca se astepata ca operatii lente de I/O sa se termine Fie urmatoarele variabile: WT = timpul mediu estimat ST= timpul mediu de rezolvare estimat pentru o cerere (fara timpii de asteptare) Atunci: WT/ST+1 thread-uri vor fi de ajuns ca sa mentina procesorul la incarcare maxima

134 12/1/2017 Clasa Executor Are doua metode statice pentru crearea de pool-uri de thread-uri ExecutorService newFixedThreadPool(int nThreads) Poate crea un pool de dimensiune fixa ExecutorService newCachedThreadPool() Creaza noi thread-uri functie de necesitati Noile thread-uri sunt adaugate la pool si reciclate ExecutorService has an execute method void execute(Runnable command)

135 { private final ServerSocket serverSocket;
class NetworkService { private final ServerSocket serverSocket; private final ExecutorService pool; public NetworkService(int port, int poolSize) throws IOException { serverSocket = new ServerSocket(port); pool = Executors.newFixedThreadPool(poolSize); } public void serve() { try for (;;) { pool.execute(new Handler(serverSocket.accept()));} } catch (IOException ex) { pool.shutdown();

136 { private final Socket socket; Handler(Socket socket)
class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() { // citeste si deserveste cererea} }

137 Referinte thread-life-cycle

138 After …. this course


Download ppt "Procesare paralela in Java"

Similar presentations


Ads by Google