2010-10-07 9 views
6

Nell'elenco di codice 5.19 del libro di Brian Goetz Concurrency In Practice, presenta la sua classe Memoizer sicura con thread finito.In Concurrency In Practice di Brian Goetz, perché c'è un po 'di tempo (vero) nell'esempio finale di una cache scalabile?

Credevo di aver capito il codice in questo esempio, solo che non capisco quello che il

while (true) 

è per all'inizio del metodo

public V compute(final A arg) throws InterruptedException 

.

Perché il codice ha bisogno del ciclo while?

Ecco l'intero codice di esempio

public class Memoizer<A, V> implements Computable<A, V> { 
    private final ConcurrentMap<A, Future<V>> cache 
     = new ConcurrentHashMap<A, Future<V>>(); 
    private final Computable<A, V> c; 

    public Memoizer(Computable<A, V> c) { this.c = c; } 

    public V compute(final A arg) throws InterruptedException { 
     while (true) { 
      Future<V> f = cache.get(arg); 
      if (f == null) { 
       Callable<V> eval = new Callable<V>() { 
        public V call() throws InterruptedException { 
         return c.compute(arg); 
        } 
       }; 
       FutureTask<V> ft = new FutureTask<V>(eval); 
       f = cache.putIfAbsent(arg, ft); 
       if (f == null) { f = ft; ft.run(); } 
      } 
      try { 
       return f.get(); 
      } catch (CancellationException e) { 
       cache.remove(arg, f); 
      } catch (ExecutionException e) { 
       throw launderThrowable(e.getCause()); 
      } 
     } 
    } 
} 
+0

La stessa cosa mi ha colpito quando l'ho letto per la prima volta. Penso di averlo segnalato http://www.javaconcurrencyinpractice.com/errata.html ma non ho mai ricevuto una risposta. – jabley

+0

Sì, forse il libro deve essere più esplicito su quella caratteristica della soluzione (riprovare all'annullamento). – russelldb

risposta

8

Etern loop riprova su CancellationException. Se viene lanciata un'altra eccezione, l'esecuzione verrà interrotta.

Biotext dot org ha uno blog entry sullo stesso problema.

+0

Sì. Ed è chiaro per me sapere che l'ho riletto. Grazie mille anche per l'ottimo collegamento. – russelldb

+0

Ma nel campione, il FutureTask non viene mai cancellato. Puoi aiutarmi a capire come potrebbe essere eseguito quel percorso di codice? – jabley

+0

FutureTask viene creato e aggiunto alla cache. Qualche altro processo potrebbe recuperare l'attività dalla cache e cancellarla. –

1

Sembra che l'obiettivo principale del codice è quello di calcolare tutto ciò che un tipo è. Sembra che l'unico modo in cui il while(true) possa mai essere efficace è se c'è una cancellazione. Se c'è una cancellazione, il metodo riproverà il calcolo.

Fondamentalmente, while(true) assicurerà che (ad eccezione di ExecutionException), ad un certo punto, la funzione verrà completata e calcolata correttamente anche con una cancellazione.

Problemi correlati