+ All Categories
Home > Documents > Comert electronic si securitatea datelor - software.ucv.rosoftware.ucv.ro/~cbadica/scd/cap5.pdf ·...

Comert electronic si securitatea datelor - software.ucv.rosoftware.ucv.ro/~cbadica/scd/cap5.pdf ·...

Date post: 31-Aug-2019
Category:
Upload: others
View: 12 times
Download: 0 times
Share this document with a friend
41
2018 -2019 Monitoare Capitolul 5
Transcript

2018 -2019

Monitoare

Capitolul 5

2018 -2019

Definirea monitoarelor

• Monitoarele ofera o alternativa disciplinata si modulara de

implementare a programarii concurente.

• Monitoarele au urmarit generalizarea conceptului de nucleu de

SO si a serviciilor asociate lui, pentru a se putea folosi acest

concept in programele concurente de uz general.

• Un monitor asigura excluderea mutuala a apelurilor

serviciilor sale de catre procese diferite. La un moment dat

numai un singur proces poate executa o operatie a

monitorului.

• Monitoarele se pot implementa in mod natural folosind obiecte.

Serviciile monitorului se implementeaza ca metode ce asigura

accesul corect la starea (datele) private ale obiectului.

2018 -2019

Incrementare atomica cu monitoare

monitor CS integer n 0 operation increment integer temp temp n n temp+1

p q

p1: CS.increment q1: CS.increment

Declararea monitoarelor

Sursa: M.Ben-Ari, 2006

• Monitoarele asigura implicit atomicitatea operatiilor, astfel ca excluderea

mutuala este asigurata in mod corect.

• Un monitor este “static” (sau “reactiv”), el asteptand doar ca operatiile

sale sa fie invocate de procese.

• Fiecare monitor dispune de un zavor (engl. lock) implicit care controleaza

intrarea in monitor. Un singur proces poate detine zavorul la un moment

dat. Daca mai multe procese asteapta la zavor, numai unul arbitrar va

reusi deci infometarea este posibila (la fel ca la semafoare)

2018 -2019

Ilustrarea monitoarelor

monitor CS

n 2

Sursa: M.Ben-Ari, 2006

2018 -2019

Variabile conditie

• Un monitor forteaza implicit excluderea mutuala a

accesului la variabilele sale. Deseori este nevoie de

cerinte explicite de sincronizare. De exemplu, in

problema producator-consumator:

• producatorul se va bloca daca tamponul este plin,

• consumatorul se va bloca daca tamponul este gol.

• Conditiile se reprezinta explicit prin declararea de

variabile conditie (engl. condition variable), numite si

evenimente (adica semnaleaza indeplinirea unor

conditii) in cadrul monitorului:

condition varCond

2018 -2019

Operatii cu variabile conditie

• Se definesc doua operatii atomice asupra variabilelor

conditie:

– waitC(varCond). Aceasta operatie realizeaza blocarea

procesului apelant la variabila conditie varCond

– signalC(varCond). Aceasta operatie realizeaza deblocarea

unui proces in asteptare la variabila conditie varCond

2018 -2019

Operatia waitC

• O variabila conditie varCond are asociata o coada de procese

blocate varCond.queue.

waitC(varCond):

varCond.queue

enqueue(varCond.queue, p)

p.state blocked

release monitor’s lock

• Procesul p care executa apelul waitC(varCond) este adaugat la

coada de procese blocate, apoi este trecut in starea blocat si se

elibereaza zavorul monitorului in care este definita variabila

varCond. Astfel, alt proces va putea intra in monitor.

2018 -2019

Operatia signalC

signalC(varCond):

if varCond.queue

(q, varCond.queue)

dequeue(varCond.queue)

q.state ready

• La executia apelului signalC(varCond) de catre un proces p, daca

coada este nevida se extrage un proces q din coada si se trece q in

starea ready.

• Observatie: nu exista cerinta ca procesul p ce a executat signalC

sa paraseasca monitorul, el putandu-si continua executia in

monitor ! Astfel, chiar daca q este ready, executia poate continua tot

cu p.

2018 -2019

Semafoare cu monitoare

monitor Sem integer s k condition notZero operation wait if s = 0 waitC(notZero) s s – 1 operation signal s s + 1 signalC(notZero)

p q

loop forever sectiune necritica p1: Sem.wait sectiune critica p2: Sem.signal

loop forever sectiune necritica q1: Sem.wait sectiune critica q2: Sem.signal

Implementarea semafoarelor cu monitoare

Sursa: M.Ben-Ari, 2006

2018 -2019

Diagrama de stari pentru problema sectiunii

critice cu semafoare implementate cu monitoare

Sursa: M.Ben-Ari, 2006

2018 -2019

Producator-consumator cu monitoare

monitor PC bufferType buffer empty condition notEmpty, not Full operation append(dataType v) if buffer is full waitC(notFull) append(x, buffer) signalC(notEmpty) operation take() dataType w if buffer is empty waitC(notEmpty) w head(buffer) signalC(notFull) return w

p q

dataType d loop forever p1: d produce p2: PC.append(d)

dataType d loop forever q1: d PC.take q2: consume(d)

Problema producator-consumator cu monitoare

Sursa: M.Ben-Ari, 2006

2018 -2019

Probleme ale strategiilor de deblocare in monitoare

• Daca p executa signalC si are ca efect trecerea lui q in starea

ready avem situatia urmatoare: – p poate continua cu urmatoarea instructiune dupa signalC

– q poate continua cu urmatoarea instructiune dupa waitC care generase

blocarea

• Insa monitorul restrictioneaza la un moment dat ca un singur

proces sa execute instructiunile monitorului. Deci fie p, fie q se

vor bloca pana cand celalalt proces elibereaza monitorul.

• Trebuie sa specificam care dintre procesul semnalizator p si

procesul in asteptare q are prioritate sau daca selectia se face

cumva arbitrar.

• Posibil mai exista si alte procese blocate la intrarea in monitor

ce vor trebui luate in considerare intr-o astfel de specificatie.

2018 -2019

Ilustrarea unui monitor cu 2 variabile conditie

monitor

condition1

condition2

waiting

waiting

monitor entry

Sursa: M.Ben-Ari, 2006

2018 -2019

Stabilirea prioritatilor proceselor blocate in monitoare

• Se introduc notatiile: – S = prioritatea proceselor semnalizatoare

– W = prioritatea proceselor blocate in asteptare pe variabile conditie

– E – prioritatea proceselor blocate la intrarea in monitor

• Exista 13 posibilitati de stabilire a prioritatilor: – 𝐶3

2 = 3 cazuri in care doua prioritati sunt egale; fiecare pereche de

prioritati egale poate fi mai mare sau mai mica decat cea de a treia,

deci in total avem 6 = 3 2 posibilitati

– 3! = 6 cazuri in care prioritatile sunt diferite

– 1 caz in care cele trei prioritati sunt egale

• Dintre cele 13 cazuri, 7 sunt respinse. Ele apar cand E >

min(S,W). Aceste situatii pot crea infometarea proceselor

semnalizatoare sau a celor in asteptare pe variabile conditie. • E>S=W, E>S>W, E>W>S

• S>E>W, W>E>S, E=S>W, E=W>S

2018 -2019

Cerinta de reluare imediata – IRR

• Varianta clasica de monitor specifica urmatoarea strategie de

stabilire a ordinii prioritatilor:

E < S < W

• Ea se numeste cerinta de reluare imediata (engl. immediate

resumption requirement – IRR) si a fost introdusa de Tony

Hoare in 1974 sub numele “signal and urgent wait”.

• Efectul este ca un proces aflat in asteptare la o variabila

conditie va fi imediat executat, inaintea procesului semnalizator

si a proceselor blocate la intrarea in monitor.

• Explicatie: procesul semnalizator a modificat starea

monitorului astfel incat conditia este satisfacuta. Procesul in

asteptare executandu-se imediat, va putea presupune ca aceasta

conditie se pastreaza astfel incat isi poate continua operatia.

2018 -2019

Lipsa IRR

• Cu ajutorul IRR, asteptarea pe conditie se poate implementa cu urmatorul

sablon, in cadrul unei operatii a unui monitor:

if not condition

waitC(varCond)

• Fara IRR, procesul semnalizator ar putea fi executat inaintea procesului in

asteptare, astfel incat conditia ar putea deveni invalidata inainte ca

procesul aflat in asteptare sa fie deblocat. Din acest motiv, in astfel de

situatii, sablonul de implementare a asteptarii pe variabila conditie este :

while not condition

waitC(varCond)

• Dezavantajul IRR este ca blocheaza procesul semnalizator si astfel

limiteaza concurenta. De aceea se recomanda ca in prezenta IRR, signalC

sa fie ultima instructiune a operatiei procesului semnalizator, astfel incat

dupa executia instructiunii signalC el va parasi monitorul, nemai fiind

nevoie sa fie blocat. Obs: vezi implementarea semafoarelor cu monitoare.

2018 -2019

Monitoare in Java

• Fiecare obiect Java are asociat un zavor implicit (engl. intrinsic

lock) care controleaza accesul firelor la obiect. In acest fel

orice obiect Java implementeaza conceptul de monitor.

• Orice fir care doreste sa acceseze (exclusiv) obiectul, trebuie sa

intre in posesia acestui zavor, si sa elibereze zavorul, dupa

terminarea accesului la obiect.

• Intre momentul intrarii in posesie si momentul eliberarii

zavorului se spune ca firul detine zavorul. Cat timp firul detine

zavorul, nici un alt fir nu poate intra in posesia lui pentru a

accesa obiectul. Orice fir ce incearca sa obtina zavorul cand

acesta este detinut de alt fir se va bloca.

2018 -2019

Metode synchonized in Java

• Mecansimul de achizitie/eliberare a unui zavor este

implementat in Java prin:

– introducerea metodelor "sincronizate" definite prin cuvantul cheie

synchronized si

– definirea unei cozi de fire pentru fiecare zavor implicit. Un fir care

incearca achizitia zavorului va fi blocat si adaugat acestei cozi.

• Un fir incearca sa intre in posesia zavorului implicit al unui

obiect executand o metoda sincronizata a obiectului. La apelul

unei alte metode sincronizate dintr-o metoda sincronizata,

procesul pastreaza zavorul. La terminarea executiei ultimului

apel al unei metode sincronizate, zavorul este eliberat.

• O clasa avand toate metodele definite cu synchronized se poate

numi in mod conventional monitor Java.

2018 -2019

Blocuri synchronized

• Folosind zavorul implicit asociat unui obiect Java, se poate

implementa facil o sectiune critica sub forma unui bloc

synchronized. Object obj = new Object();

...

synchronized(obj) {

// sectiune critica

}

• Din pacate, aceasta implementare nu ofera garantia vivacitatii,

deoarece, in prezenta accesului concurent la un astfel de bloc,

un proces arbitrar va primi accesul, fara nici o garantare a

echitabilitatii.

2018 -2019

Variabile conditie in Java

• In Java orice obiect este o variabila conditie. Astfel, clasa de

baza Object dispune de urmatoarele metode:

public final void wait() throws InterruptedException

Determina firul care o executa sa elibereze fortat zavorul si sa fie adaugat

in coada de fire a acestui obiect. Este asemanatoare cu metoda waitC.

public final void notify()

Extrage un fir din coada de fire a obiectului (daca coada nu este vida) si

il trece in starea ready. Este asemanatoare cu metoda signalC.

public final void notifyAll()

Extrage toate firele din coada de fire a obiectului (daca coada nu este

vida) si le trece in starea ready.

2018 -2019

Ilustrarea monitoarelor in Java

object

wait

notify

notifyAll

2018 -2019

Conventia “wait and notify”

• Executand wait, un fir elibereaza zavorul si este adaugat in lista in

asteptare a obiectului respectiv. Astfel ca un alt proces care era blocat in

asteptarea zavorului va putea accesa obiectul (monitorul).

• Un fir poate executa notify / notifyAll numai daca detine zavorul, si el va

continua sa-l detina dupa executia acestor apeluri. Executia notify /

notifyAll extrage unul / toate firele in asteptare la obiectul respectiv.

• Strategia IRR determina ca zavorul sa fie transmis imediat de la procesul

semnalizator S la procesul eliberat W. Insa in Java, daca zavorul devine

liber, orice alt proces (inclusiv cele eliberate cu notify / notifyAll) trebuie

sa-l (re-)achizitoneze pentru a (re-)intra in monitor.

• Deci in Java, procesele care doresc sa intre in monitor (E) si cele eliberate

(W) au aceeasi prioritate, in schimb procesul semnalizator (S) retine

zavorul, adica are prioritate mai mare. Deci avem strategia E = W < S,

numita si conventia “wait and notify”, ce a fost propusa de Lampson si

Redell in 1980.

2018 -2019

Asteptare pe conditie in Java

• Un proces care a fost deblocat nu poate presupune ca, conditia pe care

astepta este adevarata, el trebuind sa o reverifice intr-o bucla.

• Daca acea conditie este adevarata, el detinand zavorul nici un alt proces

nu o va putea modifica, astfel incat executia poate sa continue.

• Daca acea conditie este falsa, procesul va ceda zavorul si se va bloca din

nou in asteptare ca acea conditie sa devina adevarata.

synchronized void method(...) {

while (! condition) {

try {

wait();

} catch (InterruptedException e) {}

}

// Assume “condition” is true

}

2018 -2019

Semnalizare conditie in Java

• Folosirea lui notify va elibera un proces arbitrar din procesele in asteptare

pe un obiect, asa ca este posibila aparitia infometarii !

• Pentru evitarea infometarii se recomanda folosirea algoritmilor de

concurenta din pachetul java.util.concurrency.

• Daca de exemplu un monitor ar fi accesat de procese ce asteapta pe 2

conditii diferite, si am folosi notify pentru eliberarea unui proces cand una

dintre conditii devine adevarata, nu se garanteaza ca va fi eliberat firul

corect. Aceasta deoarece Java nu dispune de variabile conditie in sensul

strict. Intregul obiect va functiona ca o unica variabila conditie pentru

ambele conditii ! Din acest motiv va trebui sa deblocam toate procesele cu

notifyAll, conform schemei urmatoare:

synchronized void method(...) {

// Assume ”condition” is true

notifyAll();

}

2018 -2019

Implementarea semafoarelor cu monitoare in Java

public class MySemaphore {

private int value;

public MySemaphore (int k) {

value = k;

}

synchronized public void P()

throws InterruptedException {

while (value == 0) {

wait();

}

--value;

}

synchronized public void V() {

++value;

notify();

}

}

Daca toate procesele

asteapta pe aceeasi

conditie se poate folosi

notify.

Folosirea wait urmeaza

schema clasica a asteptarii

pe conditie fara IRR.

2018 -2019

Producator – consumator cu monitoare in Java

public class PCMonitor {

final int N = 5;

int oldest = 0, newest = 0;

volatile int count = 0;

int buffer[] = new int[N];

synchronized void append(int v) {

while (count == N) {

try {

wait(); // wait not full

} catch

(InterruptedException e){}

}

buffer[newest] = v;

newest = (newest + 1) % N;

count++;

notifyAll(); // signal not zero

}

synchronized int take() {

int temp;

while (count == 0) {

try {

wait(); // wait not zero

} catch

(InterruptedException e){}

}

temp = buffer[oldest];

oldest = (oldest + 1) % N;

count--;

notifyAll(); // signal not full

return temp;

}

}

2018 -2019

Producator in Java public class Producator extends Thread {

int q,r,max,min; // min...max, din q in q, incepand cu restul r

PCMonitor buffer;

int c = 0; // Contor de elemente trimise

public Producator(int q,int r,int min,int max,PCMonitor b) {

this.q = q; this.r = r;

this.min = min; this.max = max;

this.buffer = b;

}

int getCounter() { return c; }

public void run() {

int i = min;

while ((i % q) != r) { i++; } // determina primul numar produs

while (i <= max) {

buffer.append(i); c++;

System.out.println("Producer "+r+" produced "+i);

i += q;

}

}

}

2018 -2019

Consumator in Java public class Consumator extends Thread {

int q,r,max,min;

PCMonitor buffer;

int c = 0; // Contor de elemente consumate

public Consumator(int q,int r,int min,int max,PCMonitor b) {

this.q = q; this.r = r;

this.min = min; this.max = max;

this.buffer = b;

}

int getCounter() { return c; }

public void run() {

int i = min,k;

while ((i % q) != r) { i++; }

while (i <= max) {

k = buffer.take(); c++;

System.out.println("Consumer "+r+" consumed "+k);

i += q;

}

}

}

2018 -2019

Testare producator – consumator I

public class Main {

static final int NPTHREADS = 10;

static final int NCTHREADS = 5;

static final int MINN = 0;

static final int MAXN = 76;

static Producator pThreads[] = new Producator[NPTHREADS];

static Consumator cThreads[] = new Consumator[NCTHREADS];

static PCMonitor buffer = new PCMonitor();

public static void main(String[] args) {

int i;

System.out.println("Producator - Consumator started");

for (i=0;i<NPTHREADS;i++) {

pThreads[i] =

new Producator(NPTHREADS, i, MINN, MAXN, buffer);

pThreads[i].start();

}

2018 -2019

Testare producator – consumator II for (i=0;i<NCTHREADS;i++) {

cThreads[i] = new Consumator(NCTHREADS, i, MINN, MAXN, buffer);

cThreads[i].start();

}

for (i=0;i<NPTHREADS;i++) {

try { pThreads[i].join(); }

catch(InterruptedException e) {}

}

for (i=0;i<NCTHREADS;i++) {

try { cThreads[i].join(); }

catch(InterruptedException e) {}

}

for (i=0; i<NPTHREADS; i++) {

System.out.println(

"Producator "+i+" produced "+pThreads[i].getCounter()+" elements.");

}

for (i=0; i<NCTHREADS; i++) {

System.out.println(

"Consumator "+i+" consumed "+cThreads[i].getCounter() +" elements.");

}

System.out.println("Producator - Consumator finished");

}

}

2018 -2019

Zavoare explicite in Java

• Incepand cu versiunea 1.5, platforma Java a introdus o modalitate de a

defini zavoare explicite.

• Un zavor reprezinta mecanismul de baza ce asigura excluderea mutuala.

Numai un singur fir poate detine zavorul la un moment dat.

• Daca un fir nu poate achzitiona imediat zavorul, atunci:

– Poate incerca in mod continuu obtinerea zavorului (engl. spin), rezultand un zavor cu

filare (engl. spinning lock)

– Se poate bloca (engl. block) rezultand un zavor cu blocare (engl. blocking lock)

• Zavoarele cu filare au sens cand estimam ca timpul de asteptare este mic.

Apelul de blocare al firului poate fi costisitor.

• Zavoarele cu blocare au sens cand estimam ca timpul de asteptare este

mare. Intr-o astfel de situatie un zavor cu filare ar consuma inutil timpul

unui procesor.

• Uneori se combina cele doua tehnici: se realizeaza filaj pentru un timp

scurt, iar daca timpul de asteptare este prea mare se recurge la blocare.

2018 -2019

Interfata Lock

public interface Lock {

void lock();

void lockInterruptibly() throws InterruptedException;

boolean tryLock();

boolean tryLock(long time, TimeUnit unit);

Condition newCondition();

void unlock();

}

• Metoda lock() blocheaza apelantul pana cand achizitioneaza zavorul.

• Metoda lockInterruptibly() este identica cu lock(), dar ridica o exceptie daca

firul este intrerupt in timp ce asteapta.

• Metoda unlock() elibereaza zavorul.

• newCondition() este o metoda factory pentru crearea si returnarea de obiecte

Condition ce reprezinta variabile conditie asociate zavorului.

• Metoda tryLock() achizitioneaza zavorul daca este liber si intoarce imediat o

valoare ce arata daca achizitia a reusit sau nu. Are si varianta cu timeout.

2018 -2019

Interfata Condition

public interface Condition {

void await() throws InterruptedException;

boolean await(long time, TimeUnit unit)

throws InterruptedException;

boolean awaitUntil(Date deadline) throws InterruptedException;

long awaitNanos(long nanosTimeout) throws InterruptedException;

void awaitUninterruptibly();

void signal(); // wake up one waiting thread

void signalAll(); // wake up all waiting threads

}

• Unui zavor i se pot asocia una sau mai multe variabile conditie create cu

metoda factory newCondition().

2018 -2019

Utilizarea interfatei Condition

• Metodele await(), signal() si signalAll() au roluri similare cu wait(),

notify() si notifyAll() .

• Intrarea in monitor prin metode synchronized se inlocuieste cu apelul

metodei lock().

• Iesirea din monitor si eliberarea zavorului se inclocuieste cu metoda

unlock().

• Codul dintre apelul lock() si unlock() defineste domeniul (engl. scope)

zavorului.

• Eliberarea explicita a zavorului in monitor se face cu await() pe obiectul

Condition. Astfel un obiect Condition va inlocui variabila Object ce

reprezinta atat monitorul, cat si zavorul implicit asociat.

• Extragerea unui fir / tuturor firelor din coada zavorului se face cu una

dintre metodele signal() si signalAll().

2018 -2019

Utilizarea obiectelor Condition

Condition conditionProperty = mutex.newCondition();

...

mutex.lock()

try {

while (!property) { // not happy

conditionProperty.await(); // wait for property

}

} catch (InterruptedException e) {

... // application-dependent response

}

... // happy: property must hold

• Se observa ca asteptarea pe conditie utilizeaza acelasi sablon de programare ca si pentru zavoarele implicite. Diferente:

– Crearea variabilei conditie si asocierea ei cu zavorul

– Apelul explicit pentru achizitia zavorului

– Apelul metodei await() pe obiectul Condition respectiv

2018 -2019

Echitatea zavoarelor in Java I

• Echitatea (engl. fairness) zavoarelor este o proprietate a mecansimului

prin care este selectat un fir care va primi zavorul, din multimea tuturor

firelor care asteapta la zavor.

• Astfel, un mecanism de acces la zavor este echitabil (engl. fair) daca orice

fir care asteapta la zavor nu va fi ignorat la infinit, adica va primi la un

moment dat zavorul.

• Lipsa echitatii poate genera infometarea (engl. starvation) – o forma de

lipsa a vivacitatii (engl. liveness).

• Deseori sa apreciaza subiectiv masura echitatii achizitionarii zavoarelor:

• Asimiland eliberarea / achizitionarea zavorului cu o politica FIFO – primul fir care a

eliberat zavorul este primul care il va achizitona.

• In functie de domeniul aplicatiei: de exemplu pentru accesele concurente la un cont

bancar: i) pot avea prioritate extragerile mici fata de extragerile mari; respectiv ii)

depozitele fata de extrageri, pentru a se maximiza numarul de cereri deservite.

• In beneficiul (eficienta, performanta) platformei, independent de domeniul aplicatiei.

2018 -2019

Echitatea zavoarelor in Java II

• Echitatea zavoarelor in Java este dependenta de mecansimul particular implementat in biblioteca de programare a firelor. Acest mecanism nu este adaptat vreunei situatii particulare, singura concluzie ce se poate trage fiind urmatoarea:

Zavoarele sunt achizionate in Java pe baza unui mecanism dependent de implementare. Astfel ca implementarea zavoarelor in Java nu ofera garantia vivacitatii, deoarece, in prezenta accesului concurent la un zavor, un fir arbitrar va primi accesul, fara nici o garantie de asigurare a echitabilitatii.

synchronized, notify() si signal() nu garanteaza lipsa infometarii !

• In Java este posibila achizitia zavoarelor pe baza policii FIFO folosind zavoare reentrante – clasa ReentrantLock.

2018 -2019

Zavoare reentrante

• Utilizand algoritmi pentru sectiuni critice se pot implementa diverse clase

Lock. Ele au proprietatea ca daca un fir ce detine zavorul incearca sa-l

reachizitioneze se va crea un interblocaj: i) zavorul este deja alocat, iar

firul se va bloca in asteptarea eliberarii sale; ii) zavorul nu va fi eliberat

deoarece firul caruia i-a fost alocat nu poate progresa a.i. sa-l elibereze.

• Un zavor se numeste reentrant sau imbricat (engl. nested) daca un fir

care deja il detine, il poate reachizitiona, fara a se crea un interblocaj.

• Zavoarele implicite din Java (create cu synchronized) sunt reentrante.

• Situatii care necesita reentranta zavoarelor:

• O metoda synchronized publica apeleaza o metoda privata declarata cu synchronized

(ambele metode acceseaza data partajate de fire distincte). Dpdv tehnic, nu este

necesara declararea cu synchronized a metodelor private ale unui obiectel ce sunt

apelate doar de metode publice ale aceluiasi obiect, deja declarate cu synchronized.

• Apeluri incrucisate de metode: o metoda a obiectului 𝑜1 apeleaza o metoda a

obiectului 𝑜2 ce la randu-i apeleaza o metoda a lui 𝑜1.

2018 -2019

Clasa ReentrantLock

• Pachetul java.util.concurrent.locks furnizeaza clasa ReentrantLock pentru

implementarea zavoarelor reentrante. Ea contine pe langa metodele clasice

din interfata Lock, urmatoarele: public class ReentrantLock implements Lock {

ReentrantLock(boolean fair);

public int getHoldCount();

public boolean isLocked();

public boolean isHeldByCurrentThread();

public int getQueueLength();

}

• getHoldCount() determina de cate ori a achizitionat zavorul firul curent.

• isLocked() determina daca zavorul este detinut de vreun fir.

• isHeldByCurrentThread() determina daca zavorul este detinut de firul curent.

• getQueueLength() determina cate fire asteapta eliberarea zavorului.

• ReentrantLock(true) creaza un zavor “echitabil”, in sensul ca respecta

politica FIFO de achizitionare a zavorului.

2018 -2019

Zavoare pentru citire / scriere

• Uneori interogarea (citirea) unui obiect poate dura un timp inacceptabil de

mare. Normal nu este necesara blocarea accesului la obiect pentru citire,

ci doar pentru actualizare (scriere).

• Pentru aceasta se folosesc zavoare pentru citire / scriere (engl. read/write

locks), definite prin interfata:

public interface ReadWriteLock {

Lock readLock(); // intoarce zavorul pentru citire

Lock writeLock(); // intoarce zavorul pentru scriere

}

• O implementare a acestei interfete este ReentrantReadWriteLock ce are in

plus metodele constructor:

public class ReentrantReadWriteLock implements ReadWriteLock {

public ReentrantReadWriteLock();

public ReentrantReadWriteLock(boolean fair);

...

}

2018 -2019

Tema

1. Sa se implementeze problema filosofilor folosind monitoare.

2. Sa se implementeze problema producator-consumator folosind zavoare explicite.

3. Sa se implementeze problema filosofilor folosind zavoare explicite.


Recommended