Sunteți pe pagina 1din 12

Ministerul Educaiei al Republicii Moldova Universitatea Tehnic a Moldovei Facultatea Calculatoare Informatica i Microelectronic Catedra Automatic i Tehnologii Informaionale

Disciplina: Programarea Paralel i concurenta

RAPORT

Lucrare de laborator Nr.1

Tema: Realizarea firelor de executie n Java

A efectuat :

studentul grupei TI-101 Dovgaliuc Victor

A verificat :

profesor Ciorb Dumitru

Chiinu 2013

1. Scopul lucrrii Realizarea firelor de executie n Java 2. Indicaii teoretice Tehnicile de programare concurent integrate la nivel de limbaj au evoluat din mecanismele de programare concurent la nivel de sistem, n intenia de a oferi suport pentru creterea performanelor aplicaiilor, fr ca programatorul s fie implicat n cunoaterea unor mecanisme specifice de sistem, astfel Java ofer faciliti motenite din limbajele interpretate, obiectuale i concurente. Proiectarea i implementarea aplicaiilor folosind threaduri ofer o serie de avantaje printre care sunt: Simplificarea programrii i o mai bun stucturare a codului Eficiena n utilizarea resurselor sistemului ( modelul multithread de comunicare) mbuntirea interaciunii cu aplicaiile, prin proiectarea de interfee performante. Portabilitatea software Suport pentru planificarea i echilibrarea ncarcrii prin maparea dinamic a taskurilor la procesoare, pentru aplicatii dinamice Micorarea latenei acceselor la memorie i I-O. Java integreaz mecanismele programrii concurente sub forma unor clase specifice, oferind astfel suportul necesar programrii aplicaiilor moderne Thread -safe i suport pentru cresterea performanelor lor prin implementarea paralelismului pur pentru sisteme multiprocesor. Thread-urile native implementeaz modelul de mapare mxn i permit exploatarea caracteristicilor sistemelor multiprocesor, astfel fiecare procesor din sistem poate executa cte un thread nativ Java, nsa n acest mod toate operaiile devin operatii nucle, iar crearea distrugerea-suspendarea unui thread presupun apeluri sitem. Planificarea executiei de ctre sistemul de operare este specific fiecrui tip de thread, astfel threadurile user sunt planificate nedifereniat, ns threadurile daemon i pot ncheia execuia doar dac nu mai sunt threaduri user active. Clasa Obiect . Urmatoarele metode ale clasei Object si anume wait(), notify() si notifyAll(), sunt utilizate n programarea concurenta multithread , cu urmatoarea semnificatie : wait() - pune obiectul n asteptare pana la aparitia unui eveniment (notificare) cu- fara indicarea duratei maxime de asteptare notify() - permite anuntarea altor obiecte de aparitia unui eveniment notifyAll() - implementeaza mod broadcast notificarea mai multor obiecte la aparitia unor evenimente Alte metode ale clasei Object ,utile implementarii unor aplicatii multithread sunt:

clone() - creeaza o copie a obiectului curent finalize() - poate fi suprascrisa n clase si defineste diversele actiuni ce vor fi executate de colectorul de deseuri JVM naintea distrugerii obiectului toString() - utila conversiei obiectului n reprezentare textuala, utila activitatii de depanare Clasa Thread. Maina virtual Java permite definirea mai multor threaduri concurente, orice thread este un obiect Java, ce posed metode i poate fi transferat ca parametru, plasat ntr-un tablou. Maina virtual Java realizeaz maparea obiectului J ava de tip runnable unei implementri de thread dependent de sistem, iar sistemul de operare i aloc resurse. Orice obiect de tip thread posed o metod run() prin intermediul creia se implementeaz manifestarea threadului. Proprietile threadurilor * Threadurile posed nume pentru identificare, ns pot exista mai multe threaduri cu acelai nume, dac numele nu a fost specificat la creare, se va genera un nume nou, implicit, acesta putnd fi citit cu metoda getName(). * Orice nou thread ncepe cu execuia prin metoda start() similar nceperii execuiei unui program cu metoda main(). * Posed prioritati ( 1- 10).

Metodele clasei Thread -void start() - lanseaza n executie noul thread , moment n care executia programului este controlata de cel putin doua threaduri : threadul curent ce executa metoda start si noul thread ale carui instructiuni sunt definite n metoda run (). -void run() defineste corpul threadului nou creat , ntreaga activitate a threadului va fi descrisa prin suprascrierea acestei metode static void sleep () pune n asteptare threadul curent pentru un anumit interval de timp (msecs) -void join () - se asteapta ca obiectul thread ce apeleaza aceasta metoda sa se termine suspend() - suspendare temporara a threadului (resume() este metoda duala ce relanseaza un thread suspendat (implementarile JDK ulterioare versiunii 1.2 au renuntat la utilizarea lor) -yield() - realizeaza cedarea controlului de la obiectul thread , planificatorului JVM pentru a permite unui alt thread sa ruleze -void interrupt() trimite o ntrerupere obiectului thread ce o invoca (seteaza un flag de ntrerupere a threadului activ).

Metodele isInterrupted() si interrupted() permit testarea starii de ntrerupere a threadului apelant. Metoda interrupted() modifca starea threadului curent (la un apel secund al ei starea threadului revine la cea initiala). -static boolean interrupted() - metoda statica , testeaza daca threadul curent a fost ntrerupt, reseteaza starea interrupted a threadului current boolean isInterrupted () - testeaza daca un thread a fost ntrerupt fara a modifica starea threadului -static Thread current Thread() - returneaza obiectul reprezentnd threadul curent n executie boolean isAlive() - permite identificarea starii obiectului thread , astfel metoda returneaza true daca threadul a fost pornit si nu a murit nca,respectiv false daca threadul nu a fost pornit sau a murit, fara a putea diferentia ntre un thread ce nu a fost nca pornit, respectiv unul ce a murit. void SetDaemon(boolean on) - apelata imediat nainte de start permite definirea threadului ca daemon.Un thread este numit daemon, daca metoda lui run contine un ciclu infinit , astfel ncat acesta nu se va termina la terminarea threadului parinte. getPriority() - returneaza prioritatea threadului curent setPriority(newPriority) -permite atribuirea pentru threadul curent a unei prioritati dintr-un interval.

3. Realizarea sarcinii Threadurile se vor executa ca n figura 1.

Fig. 1 Pentru aceasta am folosit clasa java.util.concurent.CountDownLatch care conform documentaiei oficiale Oracle este un ajutor synchronizat ce permite unui sau mai multor fire sa atepte un set de operaii s fie executate de alte fire pin la momentul finisrii.

Clasa CountDownLatch se va iniializa cu un contor de tip intreg. Metoda await va bloca pn cnd contorul curent nu va fi decrementat pn la zero datorit invocrii metodei countDown(), dup care toate firele de execuie ce se afl n ateptare vor fi deblocate pentru executarea ulterior, care anterior au fost puse n ateptare prin metoda wait(). Contorul count nu poate fi resetat, n caz c avem nevoie s fie resetat vom folosi CyclicBarier. Realizarea programului n fig. 1 observam ca nodurile (1,2,3) i (8,9) se pot porni i executa concomitent deci eu am creat n program doua clase ce se vor porni concomitent A(1,2,3) i B(8,9). Ambele primesc ca parametru cite o clasa CountDownLatch care decrementeaz contorul cu o unitate de fiecare dat cnd este apelat metoda run()
public void run() { try { Thread.sleep((long)(Math.random() * 1000)); System.out.println(name); cA.countDown(); } catch (InterruptedException e) { logger.error(e); } }

Clasa C(1) avem un singur fir care este dependent de (1,2,3). El va fi instania cu 2 parametri CDL al clasei A si propriul CDL pentru punerea n asteptare al clasei E care este dependent de C.
public C(CountDownLatch cA,CountDownLatch cC, Integer name)

Executia programului ne returneaz simularea corect a grafului din Fig. 1: 3,2,1,8,4,9,5,6,7 3,8,2,5,1,9,7,4,6 Concluzie n aceast lucrare de laborator am elaborat un program ce permite instanirea si executrea unor fire de execuie simultan i n ordinea definit de mine. Am decis s utilizez anume CountDownLatch pentru c el permite gestionarea threadurilor ntr-un mod mai ordonat i intuitiv.

Bibliografie. 1. 2. 3.
http://inf.ucv.ro/~popirlan/tap/laborator8.pdf http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html HPJPC - THOMAS W. CHRISTOPHER, GEORGE K. THIRUVATHUKAL (2000).

Anex Clasa Main package md.victordov;

import org.apache.log4j.Logger;

import java.util.concurrent.CountDownLatch;

/** * Created by vdovgaliuc */ public class Main { private static Logger LOGGER = Logger.getLogger(Main.class);

public static void main(String[] args){ CountDownLatch cA = new CountDownLatch(3); CountDownLatch cB1 = new CountDownLatch(1); CountDownLatch cB2 = new CountDownLatch(1); CountDownLatch cC = new CountDownLatch(1);

//A group Thread tA1 = new Thread(new A(cA,1)); Thread tA2 = new Thread(new A(cA,2)); Thread tA3 = new Thread(new A(cA,3));

//B group Thread tB1 = new Thread(new B(cB1,8)); Thread tB2 = new Thread(new B(cB2,9));

//C group Thread tC = new Thread(new C(cA,cC,4));

Thread tD1 = new Thread(new D(cB1,5)); Thread tD2 = new Thread(new D(cB2,7));

Thread tE = new Thread(new E(cC,6));

tE.start(); tC.start();

tD1.start(); tD2.start();

tA1.start(); tB1.start(); tA2.start(); tB2.start(); tA3.start();

} } Classa B package md.victordov;

import org.apache.log4j.Logger;

import java.util.concurrent.CountDownLatch;

/** * Created by vdovgaliuc */ public class B implements Runnable { private static Logger logger = Logger.getLogger(B.class);

private CountDownLatch cB1; private Integer name;

public B(CountDownLatch cB1, Integer name){ this.cB1 = cB1; this.name = name; }

@Override public void run() { try { Thread.sleep((long)(Math.random() * 1500)); System.out.println(name); cB1.countDown(); } catch (InterruptedException e) { logger.error(e);

} } package md.victordov;

import org.apache.log4j.Logger;

import java.util.concurrent.CountDownLatch;

/** * Created by vdovgaliuc */ public class C implements Runnable {

private static Logger logger = Logger.getLogger(C.class); private CountDownLatch cA; private CountDownLatch cC; private Integer name;

public C(CountDownLatch cA,CountDownLatch cC, Integer name){ this.cA = cA; this.cC = cC; this.name = name; }

@Override public void run() { try { cA.await(); Thread.sleep((long)(Math.random() * 1000)); System.out.println(name); cC.countDown(); } catch (InterruptedException e) { logger.error(e);

} } } package md.victordov;

import org.apache.log4j.Logger;

import java.util.concurrent.CountDownLatch;

/** * Created by vdovgaliuc

*/ public class D implements Runnable { private static Logger logger = Logger.getLogger(D.class); private CountDownLatch cB; private Integer name;

public D(CountDownLatch cB, Integer name){ this.cB = cB; this.name = name; }

@Override public void run() { try { cB.await(); Thread.sleep((long)(Math.random() * 1000)); System.out.println(name); } catch (InterruptedException e) { logger.error(e);

} } package md.victordov;

import org.apache.log4j.Logger;

import java.util.concurrent.CountDownLatch;

/** * Created by vdovgaliuc

*/ public class E implements Runnable { private static Logger logger = Logger.getLogger(E.class); private CountDownLatch cC; private Integer name;

public E(CountDownLatch cC, Integer name){ this.cC = cC; this.name = name; }

@Override public void run() { try { cC.await(); Thread.sleep((long)(Math.random() * 1000)); System.out.println(name); } catch (InterruptedException e) { logger.error(e);

} }