dig*_*dug 10 java concurrency thread-safety
Brian Goetz的Java Concurrency实践提供了一个用于并发使用的高效可伸缩缓存的示例.显示类Memoizer(第108页)实现的示例的最终版本显示了这样的缓存.我想知道为什么这个类没有用@ThreadSafe注释?缓存的客户端类Factorizer已使用@ThreadSafe正确注释.附录指出,如果一个类没有使用@ThreadSafe或@Immutable注释,则应该假定它不是线程安全的.Memoizer似乎是线程安全的.
这是Memoizer的代码:
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
我猜去问戈茨吧。这可能只是一个疏忽。
然而,这些注释的问题是它们毫无意义。理想情况下,它们需要与自动错误查找器(例如 FindBugs)结合使用,在这种情况下,注释@Immutable(例如)将允许 FindBugs 打开其字段突变检测器。
如果没有这样的检查,库的作者很容易在甚至不正确的情况下附加@ThreadSafe或附加到一个类!@Immutable我并不是建议故意欺骗,而是建议诚实的错误......然而结果是图书馆的消费者不能依赖注释,所以有什么意义呢?