java concurrent locks
TRANSCRIPT
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 1/39
Paketas java.util.concurrent.locks
Nerijus Pažereckas IFF -7 1
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 2/39
Apra šymasPaketo struktūra ir naudojimasPavyzdžiai
PalyginimasIšvados
Nerijus Pažereckas IFF -7 2
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 3/39
Interfaces and classes suteikia rėmus sąlyginiamrakinimui ir laukimui (sąlyginei sinchronizacijai) kasskiriasi nuo standartinėje versijoje esančiųsinchronizacijos ir monitorių.
Sistema leidžia daug lanksčiau naudoti užraktus(locks) ir naudojimo sąlygas (conditions ), tačiau
lankstumas pasižymi sudėtingesne sintakse. java.util.concurrent.locks paketas įtrauktas nuo java1.5 versijos.
Nerijus Pažereckas IFF -7 3
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 4/39
java.util.concurrent.locks naudoja aparatūros lygiokonstrukciją įgalinančią Java programas naudotilock-free ir wait free thread-safety mechanizmus.Šių lock ir wait-free algoritmų naudojimas apsaugogijas labiau nei Objektinio lygio monitoriai(naudojant sinchronizuoti žodį).
Kitaip sakant tai Atomic priemonės, kurios turidaugiau galimybių nei objektinio lygio priemonės.
Nerijus Pažereckas IFF -7 4
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 5/39
Lock ir Būsenos objektai ( Condition) priešsynchronized žodį
Kai kuriose programose Lock objektų naudojimasyra geresnis nei synchronized naudojimas.
Užraktai (lock) leidžia nutraukti gijų laukimą arbanurodyti kiek laiko gali trukti laukimas, ko
neleidžia synchronized raktinio žodžionaudojimas.
Būsenos objektai leidžia nurodyti kelias būsenas,kuriose gijos gali laukti.
Laukiančiai gijai(-oms ) siųsdami signalą galimenurodyti, kad tam tikra sąlyga yra pasiekta.
Nerijus Pažereckas IFF -7 5
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 6/39
Paketą java.util.concurrent.locks sudaropagrindinė įgyvendinimo ReentrantLock irkitos klasės:AbstractOwnableSynchronizerLockSupport
ReentrantReadWriteLock◦ ReentrantReadWriteLock.ReadLock◦ ReentrantReadWriteLock.WriteLock
Nerijus Pažereckas IFF-7 6
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 7/39
java.util.concurrent.locks. AbstractQueuedSynchronizer
Leidžia karkasui naudoti užraktų blokavimą irsusijusius sinchronizatorius (semaphores, events,etc.) kurie paremti sąlyga pirmas - įėjo-pirmas-išėjo (first-in-first-out [FIFO]) iš eilės.
AbstractQueuedSynchronizer klasė yra naudingaapibrežiant užraktus (locks) ir kitussinchronizatorius (synchronizers) , kurie remiasi eileblokuotų gijų.
Nerijus Pažereckas IFF -7 7
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 8/39
java.util.concurrent.locks. AbstractQueuedSynchronizerMetodai:
void acquire (int args) - Acquires in exclusive mode, ignoring interrupts.void acquireInterruptibly (int arg) - Acquires in exclusive mode, aborting if interrupted.Thread getFirstQueuedThread () – gražina pirmąją ilgiausiai laukiančią gijąiš eilės arba null jei nėra laukiančių gijųCollection<Thread> getQueuedThreads () – gražina visą eilę laukiančiųgijų arba null jei tuščia kolekcijaint getQueueLength () – gražina laukiančių gijų skaičiųboolean release (int arg) - Releases in exclusive mode.protected boolean tryAcquire( int arg) – bandoma įeiti į kritinę sekcijaapsaugotu būdu (paveldi UnsupportedOperationException )
protected boolean tryRelease (int arg) – bandoma išeiti iš kritinėssekcijos apsaugotu būdu (paveldi UnsupportedOperationException )
Nerijus Pažereckas IFF -7 8
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 9/39
Naudojimas:Galima naudoti šią klasė kaip synchronizer pagrindą, taikant
šiuos metodus atominiams kintamiesiems ir kritinėmssekcijoms apsaugoti:tryAcquire(int)tryRelease(int)tryAcquireShared(int)
tryReleaseShared(int)
Nerijus Pažereckas IFF -7 9
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 10/39
Pavyzdys:Acquire:
while (!tryAcquire(arg)){ deda gij ą į eilę, jei ji dar nėra eilėje. Yra
tikimybė jog bus blokuojama esama gija }
Release:if (tryRelease(arg))Leidžia įeiti pirmam eilėje stovinčiam (laukiančiam
ilgiausiai) thred’ui ;
Svarbu žinoti, jog ši klasė veikia FIFO principu, kas reiškia, kadkritinę sekciją gali atlaisvinti tik ta gija kuri ją ir užėmė.
Nerijus Pažereckas IFF -7 10
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 11/39
java.util.concurrent.locks. LockSupport
Pagrindinė klasė gijų blokavimui kuriant užraktus(locks) ir kitas sinchronizacijos klases(synchronization classes).
Ši klasė naudojama kai reikia žemo lygio blokavimų(lower-level blocking) ir atblokavimų palaikymo,kurie naudingi programuotojams įgyvendinantiemssavo individualių užraktų (lock) klases.
Nerijus Pažereckas IFF -7 11
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 12/39
Metodai:static void park() - Disables the current thread for thread
scheduling purposes unless the permit is availablestatic void parkNanos (long nanos) - Disables the currentthread for thread scheduling purposes, for up to the specifiedwaiting time, unless the permit is available.static void parkUntil (long deadline) - Disables the current
thread for thread scheduling purposes, until the specifieddeadline, unless the permit is available.static void unpark (Thread thread) - Make available the permitfor the given thread, if it was not already available.
Nerijus Pažereckas IFF -7 12
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 13/39
Naudojimas:Naudojimas pana šus kaip ir Semaforų (semaphore),
tačiau paremta FIFO principu ir negalime sumuoti(counting) , kaip kad galėjome su semaforais.Naudojimas pakankamai sunkus, patartina geriau
naudoti Semaphore nei Park’ingą.
Nerijus Pažereckas IFF -7 13
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 14/39
Pavyzdys:class FIFOMutex {
private AtomicBoolean locked = new AtomicBoolean(false);private Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>();
public void lock() {boolean wasInterrupted = false;Thread current = Thread.currentThread();waiters.add(current);
// Block while not first in queue or cannot acquire lockwhile (waiters.peek() != current || !locked.compareAndSet(false, true)) {
LockSupport.park();
if (Thread.interrupted()) // ignore interrupts while waitingwasInterrupted = true;
}
waiters.remove();if (wasInterrupted) // reassert interrupt status on exit
current.interrupt();}
public void unlock() {locked.set(false);LockSupport.unpark(waiters.peek());
}}
Nerijus Pažereckas IFF -7 14
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 15/39
java.util.concurrent.locks. ReentrantReadWriteLock
Turi dukterines klases:◦ ReentrantReadWriteLock.ReadLockIšplėstiniams skaitymo užraktams kurti
◦ ReentrantReadWriteLock.WriteLockIšplėstiniams rašymo užraktams kurti
Nerijus Pažereckas IFF -7 15
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 16/39
Metodai:protected Thread getOwner() - Returns the thread that
currently owns the write lock, or null if not owned.protected Collection<Thread> getQueuedReaderThreads() -Returns a collection containing threads that may be waiting toacquire the read lock.protected Collection<Thread> getQueuedThreads() - Returns
a collection containing threads that may be waiting to acquireeither the read or write lock.protected Collection<Thread> getQueuedWriterThreads() -Returns a collection containing threads that may be waiting toacquire the write lock.
Nerijus Pažereckas IFF -7 16
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 17/39
Metodai:boolean isWriteLocked() - Queries if the write lock
is held by any thread.ReentrantReadWriteLock.ReadLock readLock() -Returns the lock used for reading.ReentrantReadWriteLock.WriteLock writeLock() -Returns the lock used for writing.int getReadLockCount() - Queries the number of read locks held for this lock.int getWriteHoldCount() - Queries the number of reentrant write holds on this lock by the current
thread.Boolean hasWaiters( Condition condition) - Querieswhether any threads are waiting on the givencondition associated with the write lock.
Nerijus Pažereckas IFF -7 17
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 18/39
Naudojimas:Naudojama kritinės sekcijos apsaugai, kuomet
kritinėje sekcijoje apsaugom kintamąjį (objektą),prie kurio vienu metu gali prieiti skaitymo ir rašymogijos.
Skaitymo gija įėjus į KS užrakina “rašymo” gijas,
tačiau visos gijos kurios nekeis reikšmės gali įeiti įKS, po to jeigu į KS įeina rašymo gija, negali įeitiskaitymo gijos.
Nerijus Pažereckas IFF -7 18
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 19/39
Pavyzdys Nr 1:class X {ReadWriteLock rw = new ReentrantReadWriteLock() ;// ...
/* Operacija A rašo */public void A() throws InterruptedException {rw.writeLock().lock(); // užrakina rašymo užraktątry {Kritin ė sekcija A
}finally {rw.writeLock().unlock(); // Atrakina rašymo užraktą
}}
/*Operacija B skaito*/public void B() throws InterruptedException {rw.readLock().lock(); // Užrakina skaitymo užraktątry {Kritinė sekcija B
}finally {rw.readLock().unlock(); // atrakina skaitymo užraktą
}}
}
Nerijus Pažereckas IFF -7 19
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 20/39
Pavyzdys Nr 2:class CachedData {
Object data;volatile boolean cacheValid;ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
void processCachedData() {rwl.readLock().lock();if (!cacheValid) {
// atnaujinamas užraktas rankiniu būdu// pirmiausia reikia atrakinti norint gauti rašymo užraktą
rwl.readLock().unlock();rwl.writeLock().lock();if (!cacheValid) { // sąlyga
data = ...cacheValid = true;
}// sumažinam užraktus (užraktų saugumą)rwl.readLock().lock();
rwl.writeLock().unlock(); // atrakinam rašymą, tačiau laikom skaitymą}
use(data);rwl.readLock().unlock();
}}
Nerijus Pažereckas IFF -7 20
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 21/39
java.util.concurrent.locks. ReentrantLock
Klasė naudojama užraktų (locks) būsenoms/elgesiuistebėti ir vykdyti, panašiai veikia kaip irsynchronized metodai, tačiau turi platesniųgalimybių.
Pagrindinė klasė naudojama KS (kritinės sekcijos)apsaugai. Leidžia vienai gijai įeiti į kritinę sekcija irkol ji neišėjo, visi kiti laukia.
Nerijus Pažereckas IFF -7 21
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 22/39
Metodai:Int getHoldCount () - Queries the number of holds on this lock bythe current thread.
protected Thread getOwner () - Returns the thread that currentlyowns this lock, or null if not owned.protected Collection<Thread> getQueuedThreads () - Returns acollection containing threads that may be waiting to acquire thislock.int getQueueLength () - Returns an estimate of the number of
threads waiting to acquire this lock.protected Collection<Thread> getWaitingThreads (Conditioncondition) - Returns a collection containing those threads thatmay be waiting on the given condition associated with this lock.int getWaitQueueLength (Condition condition) - Returns an
estimate of the number of threads waiting on the given conditionassociated with this lock.boolean hasQueuedThread (Thread thread) - Queries whether thegiven thread is waiting to acquire this lock.boolean hasQueuedThreads () - Queries whether any threads are
waiting to acquire this lock.
Nerijus Pažereckas IFF -7 22
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 23/39
Metodai:boolean hasWaiters (Condition condition) - Queries whether any
threads are waiting on the given condition associated with this
lock.boolean isFair() - Returns true if this lock has fairness set true.boolean isHeldByCurrentThread() - Queries if this lock is held by
the current thread.boolean isLocked() - Queries if this lock is held by any thread.void lock() - Acquires the lock.
Condition newCondition() - Returns a Condition instance for usewith this Lock instance.String toString() - Returns a string identifying this lock, as well as
its lock state.boolean tryLock() - Acquires the lock only if it is not held by
another thread at the time of invocation.
boolean tryLock (long timeout, TimeUnit unit) - Acquires the lockif it is not held by another thread within the given waiting timeand the current thread has not been interrupted.void unlock() - Attempts to release this lock.
Nerijus Pažereckas IFF -7 23
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 24/39
Naudojimas:Tai pagrindinė klasė užraktų (lock) naudojimui. Lengviausiai
naudojama iš pateiktų klasių ir lengviausiai suprantama jeiturimas supratimas apie Semaphore bei Monitors įrankius irsynchronized metodus.
Klasė naudinga tuo, jog yra didesnių galimybių nei susemaforais ar monitoriais.
Lock naudojimas pranašesnis klaidų apdorojimo bibliotekospaveldėjimu.Kiekvienas metodas kurio pradžioje yra žodelis try paveldi
InterruptedException klaidų vengimo biblioteką. Tai metoduspadaro lankstesnius ir saugesnius.
Nerijus Pažereckas IFF -7 24
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 25/39
Naudojimas:public Condition newCondition () metodas paveldi Object
stebėjimo metodus, kitaip tariant monitoriaus būsenas (wait,notify, notifyAll) . Todėl jei norime kritinę sekciją apsaugotinaudodami kelis užraktus, galime vartoti ši metodą, kadporeikiui esant išplėstume gijų būsenas.
Nerijus Pažereckas IFF -7 25
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 26/39
Pavyzdys Nr 1 ( ReentrantLock lock ) :
class X {private final ReentrantLock lock = newReentrantLock();
// ...
public void m() {lock.lock() ; // block until condition holdstry {
// Kritinė sekcija} finally {
lock.unlock()}
}}
Nerijus Pažereckas IFF-7 26
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 27/39
Pavyzdys Nr 2 ( getHoldCount() ) :
class X {ReentrantLock lock = new ReentrantLock();// ...public void m() {
assert lock.getHoldCount() == 0;
lock.lock();try {
// KS} finally {
lock.unlock();
}}
}
Nerijus Pažereckas IFF -7 27
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 28/39
Pavyzdys Nr 3 ( Condition naudojimas ) :class BoundedBuffer {
final Lock lock = new ReentrantLock();final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
public void put(Object x) throws InterruptedException {...
}public Object take() throws InterruptedException {
...}
Nerijus Pažereckas IFF -7 28
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 29/39
Pavyzdys Nr 3 ( Condition naudojimas ) :public void put(Object x) throws InterruptedException {
lock.lock();try {
while (count == items.length)notFull .await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;++count;notEmpty .signal();
} finally {lock.unlock();
}}
Nerijus Pažereckas IFF -7 29
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 30/39
Pavyzdys Nr 3 ( Condition naudojimas ) :
public Object take() throws InterruptedException {lock.lock();try {
while (count == 0)notEmpty .await();
Object x = items[takeptr];if (++takeptr == items.length) takeptr = 0;--count;notFull .signal();return x;
} finally {lock.unlock();
}}
Nerijus Pažereckas IFF -7 30
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 31/39
Pavyzdys Nr 4 ( sleep ir tryLock(time, TimeUnit)) :
Uzrakinta gija: Gija_1Negalima uzrakinti gijos: Gija_2 nes kita gija siuo
metu kritinese sekcijoje. Bandysim veliau.Atrakinta gija kuri iki siol vykde savo veiksmus:
Gija_1Uzrakinta gija: Gija_2
Atrakinta gija kuri iki siol vykde savo veiksmus:Gija_2
Rodyti vaizdžiai
Nerijus Pažereckas IFF -7 31
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 33/39
Naudojant java.util.concurrent.locks paketą, galimeimituoti bet kurią concurrent bibliotekos priemonę:
semaphore, monitor, synchronized.Štai keli pavyzdžiai kaip tai atrodo ir kokie yraskirtumai.
Nerijus Pažereckas IFF -7 33
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 34/39
Palyginimas: Lock prieš synchronized objektus
Nerijus Pažereckas IFF -7 34
synchronized lock
Object monitorObject;synchronized ( monitorObject ){
// Kritinė sekcija
}
Lock lockObject ;try{
lockObject .lock();
// Kritinė sekcija}finally{
lockObject .unlock();}
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 35/39
Palyginimas: Lock prieš Monitor
Nerijus Pažereckas IFF -7 35
Monitor Lock
boolean somecondition ; // laukimo sąlygawhile( somecondition ){
wait();}
Condition conditionVariable =lockObject.newCondition();boolean somecondition ; // laukimo sąlygawhile( somecondition ){
conditionVariable.await();}
boolean somecondition ; // laukimo sąlygaif( someothercondition ) {
notify();}
boolean somecondition ; // laukimo sąlygaif( someothercondition ) {
conditionVariable.signal();}
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 36/39
Kodėl turėčiau naudoti locks paketą?
Nerijus Pažereckas IFF -7 36
Jeigu iki šiol naudojate semaforus ar monitorius ir pilnai suprantate kaip juos valdyti ir tinkamai pritaikyti, tai ir toliau juos naudokite.Vis dėl to yra keletas privalumų naudojant naująjį atomic lygiagretumą:
o Naudojant Objektinio lygio monitorius arba sinchronizaciją yra dideliolygio perpildymas, o naudojant atomic priemones tokias kaip lock
perpildymas lygiagretumo metu nežymus.o Naudojant objektinio lygio sinchronizavimo priemones tokias kaipSemaphore labai sunku padaryti gerą sinchronizavimą, o naudojant Lockpriemones lengva apsaugoti kritinę sekciją.
o Atomic priemonės suteikia didesnį atsparumą nuo aklavietės(deadlock) ar prioritetinės inversijos, nei objektinio lygio lygiagrečiosiospriemonės.
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 37/39
Yra keletas aiškių privalumų naudotis nauja "Java“ atomic lygiagrečiomispriemonėmis, tačiau reikia ir kai ką žinoti:
o Įsitikinkite, jog suprantate kaip naudotis jomis prieš pradėdaminaudotis. Jei esate įsitikinęs jog mokate naudotis synchronizedmetodais, tuomet nepulkite perrašinėti viso kodo naujomispriemonėmis. Jau geriau turėti lėtą, bet patikimą kodą (priemones),negu greitą, tačiau – mažiau stabilią programą.
o Prieš naudojant atomic priemones jau parašytoje programoje,
įsitikinkite jog savo programoje nenaudojate pasenusių priemoniųlygiagretumui įgyvendinti, nes ši naujoji biblioteka atsirado tik suJava 1.5 versija, todėl galimi nesuderinamumai.
Nerijus Pažereckas IFF -7 37
8/14/2019 Java Concurrent Locks
http://slidepdf.com/reader/full/java-concurrent-locks 38/39
Jei esate patenkintas naudojamomis lygiagrečiomispriemonėmis, tuomet jas ir naudokite vietoj to, kad
pradėtumėte naudoti menkai žinomą priemonę.Tačiau jeigu jums neužtenka naudojamų priemonių,išbandykite naująjį Locks paketą, nes jei suprasitekaip juo naudotis, jūsų programa taps greitesnė,saugesnė, stabilesnė ir mažiau apkraus procesorių.
Nerijus Pažereckas IFF -7 38