Sunteți pe pagina 1din 32

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Programare concurenta in Java

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Premise
Programarea concurenta in Java tine cont de
constrangerile impuse de sistemul de operare
procesele nu pot partaja date
firele de executie (thread) din acelasi proces pot
orientarea pe obiecte
datele sunt grupate in obiecte impreuna cu operatiile
care le manipuleaza
Discutam in continuare ambele aspecte

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Procese
Proces

Proces 1

Instanta a unui program in


executie

Proces 2

Process
Control Block

Process
Control Block

Cod

Cod

Date

Date

Stiva

Stiva

Pentru un proces, SO aloca:


Un spatiu in memorie
(codul programului, zona
de date, stiva)
Controlul anumitor resurse
(fisiere, dispozitive I/O, )

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Fire de executie
Un proces poate avea mai
multe fire de executie
Fir de executie (thread):

Process
Control Block

Flux de control secvential in


cadrul unui proces

Cod

Firele de executie
impart acelasi spatiu de
adrese;
au in comun: zonele de cod si
date din memorie, resursele
procesului
zona de stiva reprezinta
starea curenta a thread-ului si
este proprie thread-ului

Date

Thread 1

Thread 2

Thread
Control Block

Thread
Control Block

Stiva

Stiva

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Executia thread-urilor

P1

Thread 1

P2

Sisteme multiprocesor:
executie in paralel

Thread 2
t

Sisteme uniprocesor:

T1 T2

executie secventiala
planificarea este realizata
de sistemul de operare

P1
t

Algoritmmi paraleli si distribuiti

Politici: divizarea timpului


(time sharing) cu planificare
round robin sau prioritati

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Avantajele utilizarii firelor de executie


Partajarea datelor in Java
Un proces nu poate partaja direct date cu un alt proces
Doua fire de executie ale aceluiasi proces pot accesa direct date
din memoria partajata
Imbunatatirea productivitatii prin utilizarea concurenta a resurselor
In sistemele multiprocesor: utilizarea simultana a procesoarelor
In general: utilizarea simultana a diverselor resurse (ex: in timp
ce se asteapta la un dispozitiv I/O se pot executa alte operatii cu
procesorul)
Structurarea mai buna a programelor mai multe unitati de executie
Diferenta fata de procese: crearea unui nou fir de executie este mai
simpla
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Programare concurenta in Java


Limbajul ofera suport pentru fire de executie
Pentru crearea firelor de executie:
Clasa java.lang.Thread
Interfata Runnable
Metode specifice clasei Thread:
start(), sleep(), getPrority(),
setPriority()
Metode specifice clasei Object:
wait(), notify()

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Exemplu: Crearea unui fir de executie


Class MyThread extends Thread {
public void run() {

sleep(100);

}
}

MyThread mt = new MyThread();

mt.start();

Class MyModule extends Module


implements Runnable {
public void run() {

Thread t =
Thread.currentThread();
t.sleep(100);

}
}

MyModule mm = new MyModule();


Thread mmt = new Thread(mm);

mmt.start();

def. noua clasa extinde Thread


def. metoda run (corpul thread-ului) def. noua clasa implementeaza Runnable
creaza o instanta (new)
def. metoda run
porneste thread-ul (start)
creaza instanta si paseaza constructorului
thread + porneste thread-ul
este nevoie de o variabila thread pentru a
apela metode specifice (sleep() )
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Starile posibile ale unui thread


Creat: obiectul a fost creat cu operatia new() dar nu
functioneaza inca; se poate apela metoda start()

Gata de executie: a fost apelata metoda start(),


threadul poate fi executat
Suspendat: a fost apelat sleep() sau wait()
Terminat: metoda run() a fost terminata

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Sincronizarea firelor de executie


Doua situatii:
Concurenta la accesul resurselor excludere mutuala
(atomicitatea operatiilor)
Cooperare orchestrarea operatiilor firelor de executie
pentru asigurarea corectitudinii aplicatiilor

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Procese nesincronizate - pseudocod


var a: int := 0; b: int := 0;
tipareste GATA main!
co f1::
fa i := 0 to 2
tipareste 1, a, b;
a := a+1;
b := b+1
af;
tipareste GATA
|| f2::
fa i := 0 to 2
tipareste 2, a, b;
a := a+1;
b := b+1
af;
tipareste GATA

oc
Algoritmmi paraleli si distribuiti

Rezultat posibil

GATA main!
2 a = 0 b =
1 a = 0 b =
1 a = 2 b =
2 a = 3 b =
1 a = 4 b =
2 a = 5 b =
GATA!
GATA!

0
0
1
2
3
4

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Programare concurenta fire nesincronizate


Class FirNeSincronizat extends Thread {
static int a = 0, b = 0;
FirNeSincronizat (String nume) {
super(nume);
//asociaza un nume obiectului
}
void metoda() {
System.out.println(getName() + a= + a + b= + b);
a++;
try {
sleep((int)Math.random() * 1000));
} catch (InterruptedException e) {}
b++;
}

public void run() {


for (int i = 0; i < 3; i++) {
metoda();
}
System.out.println(GATA!);
}

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Scenariu de executie
class TestSincronizare extends Thread {
public static void main (String args[]) {
FirNeSincronizat f1 = new FirNeSincronizat(1);
FirNeSincronizat f2 = new FirNeSincronizat(2);
f1.start(); f2.start();
System.out.println(GATA main!);
}
}
Rezultat

GATA main!
2 a = 0 b =
1 a = 0 b =
1 a = 2 b =
2 a = 3 b =
1 a = 4 b =
2 a = 5 b =
GATA!
GATA!

0
0
1
2
3
4

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Sincronizarea prin excludere mutuala


Asigura excluderea mutuala un singur thread poate executa la
un moment dat o metoda (sau o secventa de cod) sincronizata:
sectiune critica (corespunde cu < > din pseudocod)
Excluderea mutuala foloseste mecanismul de zavor :
Fiecare obiect are asociat un zavor (lock)
synchronized(o) asigura intrarea in sectiunea critica
se poate asocia unei metode sau unei secvente de cod
pe parcursul executiei secventelor de cod sincronizate, zavorul
este inchis

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Procese sincronizate pseudocod


var a: int := 0; b: int := 0;
tipareste GATA main!
co f1::
fa i := 0 to 2
<tipareste 1, a, b;
a := a+1;
b := b+1>
af;
tipareste GATA
|| f2::
fa i := 0 to 2
<tipareste 2, a, b;
a := a+1;
b := b+1>
af;
tipareste GATA

oc
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Exemplu: Sincronizare pentru accesul concurent la o


resursa (1)
Class FirSincronizat extends Thread {
static int a = 0, b = 0;
static Object o = new Object(); //folosit in sincroniz.
FirSincronizat (String nume) {
super(nume);
}
void metoda() {
System.out.println(getName() + a= + a + b= + b);
a++;
try {
sleep((int)Math.random() * 1000));
} catch (InterruptedException e) {}
b++;
}

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Exemplu: Sincronizare pentru accesul concurent la o


resursa (2)

public void run() {


for (int i = 0; i < 3; i++) {
synchronized(o) {
//sincronizare asociata cu metoda
metoda();
}
}
System.out.println(GATA!);
}

class TestSincronizare extends Thread {


public static void main (String args[]) {
FirSincronizat f1 = new FirSincronizat(1);
FirSincronizat f2 = new FirSincronizat(2);
f1.start(); f2.start();
System.out.println(GATA main!);
}
}
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Efectul sincronizarii
doua secvente sincronizate de acelasi obiect nu se pot executa in
acelasi timp
adica operatiile celor doua secvente sa se intreteasa
cand un thread executa o secventa sincronizata de un obiect, alte
threaduri care incearca sa execute secvente sincronizate de
acelasi obiect se blocheaza pana cand executia primei secvente
se termina
Ex. cand f1 executa secventa sincronizata de obiectul o, f2 nu
poate executa secventa sincronizata de acelasi obiect (chiar daca
f1 este in "sleep")

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Orchestrarea firelor de executie


Ce se intampla daca un thread se blocheaza pe parcursul
executiei unei metode sincronizate?
sincronizarea prin wait si notify

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Metoda wait()
Permite manevrarea zavorului asociat cu un obiect
La apelul metodei wait() pentru un obiect o de catre un
thread t:
se deblocheaza zavorul asociat cu o; t este adaugat
la un set de thread-uri blocate, wait set-ul lui o
daca t nu detine zavorul pentru o:
IllegalMonitorStateException
t va continua executia doar cand va fi scos din wait
set-ul lui o, prin:
o operatie notify() / notifyAll(),
expirarea timpului de asteptare, sau
o actiune dependenta de implementare
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Notificari
Metode: notify(), notifyAll()
La o notificare apelata din thread-ul t pentru obiectul o:
notify(): un thread u din wait set-ul lui o este scos si
repus in executie
notifyAll(): toate thread-urile sunt scoase din wait
set-ul lui o dar numai unul va putea obtine zavorul
daca t nu detine zavorul pentru o:
IllegalMonitorStateException

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Producator-consumator - pseudocod
var buf: int, p: int :=0, c:int :=0;
co Producer:: var a: array[1:n] of int;
do p<n -> <await p=c>;
buf := a[p+1];
p := p+1
od
Consumer:: var b: array [1:n] of int;
do c<n -> <await p>c>;
b[c+1] := buf;
c := c+1
od
oc
4 October 2010

Algoritmim paraleli si distribuiti

22

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Implementare Java
buf implementat
ca o clasa
ZonaTampon cu
doua metode:
Produ
Consuma
valorile a
sunt
produse la
executie

valorile b sunt
tiparite

Algoritmim paraleli si distribuiti

23

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Comunicarea prin tampon comun in Java concurent


class ZonaTampon {
// valoarea curenta din tampon

private int buf;

private boolean disponibil = false;


public synchronized int Consuma() {
if (!disponibil) {

// valoare indisponibila

try {
wait();
} catch (InterruptedException e) {}
}
disponibil = false;
notify();
return buf;
}
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Comunicarea prin tampon comun in Java concurent


public synchronized void Produ(int valoare) {
if (disponibil) {

// o valoare este in tampon

try {
wait();
} catch (InterruptedException e) {}
}
buf = valoare;
disponibil = true;
notify();
}
}

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Exemplu Producator
Class Producator extends Thread {
private ZonaTampon Tampon;
private int numar;
// ID-ul producatorului
public Producator(ZonaTampon z, int numar) {
Tampon = z; this.numar = numar;
}
public void run() {
for (int i = 0; i < 10; i++) {
Tampon.Produ(i);
System.out.println(Producator + this.numar + a
transmis: + i);
try {
sleep((int)Math.random() * 100));
} catch (InterruptedException e) {}
}
}
}
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Exemplu - Consumator
class Consumator extends Thread {
private ZonaTampon Tampon;
private int numar; // ID-ul consumatorului
public Consumator(ZonaTampon z, int numar) {
Tampon = z;
this.numar = numar;
}
public void run() {
int valoare = 0;
for (int i = 0; i < 10; i++) {
valoare = Tampon.Consuma();
System.out.println(Consumator + this.numar + a
preluat + valoare);
}
}
}
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Exemplu - Test
public class TestProducatorConsumator {
public static void main(String[] args) {
ZonaTampon z = new ZonaTampon();
Producator p1 = new Producator(z, 1);
Consumator c1 = new Consumator(z, 1);
p1.start();
c1.start();
}
}

Tema: ce rezultat produce programul prezentat?

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Alte info: Suportul pentru concurenta in JDK 1.5


Pachet nou: java.util.concurrent
Imbunatatiri:
Schimbari la nivelul masinii virtuale: exploatarea noilor
instructiuni disponibile la procesoarele moderne
Clase utilitare de baza: lock-uri, variabile atomice
Clase de nivel inalt: semafoare, bariere, pool-uri de fire
de executie

Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Clase utile pentru sincronizare in JDK 1.5


(din pachet java.util.concurrent)
Semaphore
Mutex
CyclicBarrier
bariera reutilizabila; are ca argument un contor care arata
numarul de threaduri din grup

CountdownLatch
similar cu bariera, are un contor, dar decrementarea contorului
este separata de asteptarea ajungerii la zero thread-urile care
gasesc zero trec fara sa astepte

Exchanger
rendezvous cu schimb de valori in ambele sensuri intre threaduri
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Facilitati pentru sincronizare de nivel scazut JDK 1.5


Lock
generalizare lock monitor cu asteptari contorizate,
intreruptibile, teste etc.
ReentrantLock
Condition
permite mai multe conditii per lock
ReadWriteLock
mai multi readers un writer
Variabile atomice: AtomicInteger,
AtomicLong, AtomicReference,
permit executia atomica "read-modify-write"
Algoritmmi paraleli si distribuiti

Universitatea Politehnica Bucureti - Facultatea de Automatic i Calculatoare

Referinte
[Ath02] Irina Athanasiu, Java ca limbaj pentru programarea
distribuita, MatrixRom, 2002
[JLS05] http://java.sun.com/docs/books/jls/ - The Java Language
Specification
[J2SE05N] http://java.sun.com/developer/technicalArticles/
releases/j2se15/ - J2SE 5.0 in a Nutshell
http://www.cs.cf.ac.uk/Dave/C/node29.html - Threads: Basic
Theory and Libraries

Algoritmmi paraleli si distribuiti

S-ar putea să vă placă și