2013-08-28 18 views

risposta

0

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.

  1. Si desidera che i thread in attesa siano selezionati in modo corretto.
  2. Si desidera utilizzare il metodo tryLock().
  3. Si desidera interrompere un thread in attesa e farlo fare qualcos'altro.
  4. 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.

2

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 usando synchronized 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.

+0

Questo, e c'è un '' '' ReentrantReadWriteLock''' che può essere utile. Sarebbe fastidioso implementare con '' 'synchronized'''. –

6

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(); 
     } 
    } 
} 
+2

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. –