Quando eseguo la classe di esempio a http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html, sto vedendo lo stesso comportamento di synchronized
.qualcuno può spiegare come usare Reentrant Lock in java su Synchronized con alcuni migliori esempi
qualcuno può spiegare come usare Reentrant Lock in java su Synchronized con alcuni migliori esempi
risposta
No, generalmente non si noterà alcuna differenza di comportamento. Ma come dice il sito web, ci sono un paio di casi che ti consigliamo di utilizzare uno ReentrantLock
anziché synchronized
.
- Si desidera che i thread in attesa siano selezionati in modo corretto.
- Si desidera utilizzare il metodo tryLock().
- Si desidera interrompere un thread in attesa e farlo fare qualcos'altro.
- Le prestazioni di ReentrantLock sono migliori di quelle sincronizzate, e ti interessa.
Se non è necessario alcuno di questi miglioramenti, l'utilizzo di synchronized
va bene e potrebbe non essere possibile rilevare la differenza.
Da the JavaDoc of the ReetrantLock class:
Un rientrante mutua esclusione
Lock
con lo stesso comportamento di base e semantica come il blocco del monitor implicito accessibili usandosynchronized
metodi e dichiarazioni, ma con funzionalità estese.
Nell'esempio, non si utilizzano le "funzionalità estese"; si utilizza ReentrantLock
come alternativa equivalente al metodo synchronized
(tranne che con l'istruzione synchronized
, si utilizza this
come blocco). Quindi i due metodi devono comportarsi allo stesso modo.
Qui ci sono tre modi, metodi, di un thread che accede a un blocco e uno per rilasciare il blocco. Potresti provare a implementarli usando la parola chiave synchronized
. Le funzionalità estese ei vantaggi dell'utilizzo di ReentrantLock
diventeranno evidenti.
public class DoorLockUsingLock {
private int counter= 0;
private Thread owner= null;
private Lock l = new ReentrantLock();
private Condition notLocked= l.newCondition();
public void lockItDown() throws InterruptedException {
l.lockInterruptibly();
try {
while ((counter> 0) && (owner!= Thread.currentThread())) {
notLocked.await();
}
counter++;
owner = Thread.currentThread();
} finally {
l.unlock();
}
}
public void lockItDownUninterruptibly() {
l.lock();
try {
while ((counter > 0) && (owner != Thread.currentThread())) {
notLocked.awaitUninterruptibly();
}
counter++;
owner= Thread.currentThread();
} finally {
l.unlock();
}
}
public boolean tryLockItDown(long timeout, TimeUnit unit) throws InterruptedException {
long time = unit.toNanos(timeout);
long end = System.nanoTime() + time;
boolean success = l.tryLock(timeout, unit);
if (!success) {
return false;
}
try {
time = end- System.nanoTime();
while ((counter> 0) && (owner != Thread.currentThread()) && (time > 0)) {
notLocked.await(time, TimeUnit.NANOSECONDS);
time = end - System.nanoTime();
}
if (time > 0) {
counter++;
owner = Thread.currentThread();
return true;
}
return false;
} finally {
l.unlock();
}
}
public void unlockIt() throws IllegalMonitorStateException {
l.lock();
try {
if (counter== 0) {
throw new IllegalMonitorStateException();
}
if (owner!= Thread.currentThread()) {
throw new IllegalMonitorStateException();
}
counter--;
if (counter == 0) {
owner = null;
notLocked.signal();
}
} finally {
l.unlock();
}
}
}
In pratica riproduce '' 'synchronized''',' 'wait''' e' '' notify'''. '' 'ReentrantLock''' e' '' Condition''' ripuliscono la semantica e consentono l'equità, ma sono per lo più la stessa cosa. –
Questo, e c'è un '' '' ReentrantReadWriteLock''' che può essere utile. Sarebbe fastidioso implementare con '' 'synchronized'''. –