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());
}
}
}
}
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
Sì, forse il libro deve essere più esplicito su quella caratteristica della soluzione (riprovare all'annullamento). – russelldb