comert electronic si securitatea datelor - software.ucv.rosoftware.ucv.ro/~cbadica/scd/cap5.pdf ·...
TRANSCRIPT
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
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
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);
...
}