在Brian Goetz的书“Concurrency In Practice”的代码清单5.19中,他展示了他完成的线程安全的Memoizer类。
我以为我理解了这个例子中的代码,除了我不明白
while ( true )
是
的开头public V compute(final A arg) throws InterruptedException
方法。
为什么代码需要while循环?
以下是整个代码示例
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 :(得分:8)
CancellationException上的永久循环重试。如果抛出任何其他异常,则执行将被停止。
Biotext dot org在同一问题上有一个blog entry。
答案 1 :(得分:1)
看起来代码的主要目标是计算A的类型。似乎while(true)
能够有效的唯一方法是取消。如果取消,则该方法将重试计算。
基本上,while(true)
将确保(除了ExecutionException之外),在某些时候,即使取消,该函数也会完成并正确计算。