java concurrent locks

39
Paketas java.util.concurrent.locks Nerijus Pažereckas IFF-7 1

Upload: pastas4788

Post on 30-May-2018

239 views

Category:

Documents


0 download

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 32/39

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

8/14/2019 Java Concurrent Locks

http://slidepdf.com/reader/full/java-concurrent-locks 39/39

Ačiū už dėmesį !