搬砖自<Java并发编程>
private final Map<A,Future<V>> cache = new ConcurrentHashMap<>();
private final Computable<A,V> c;
public Memoizer4(Computable c) {
this.c = c;
}
@Override
public V compute(A arg) throws InterruptedException {
Future<V> result = cache.get(arg);
if (result == null) {
Callable<V> eval = new Callable<V>() {
@Override
public V call() throws Exception {
return c.compute(arg);
}
};
FutureTask<V> ft = new FutureTask<>(eval);
result = ft;
cache.putIfAbsent(arg, result);
ft.run();
}
try {
V ret = result.get();
return ret;
} catch(Exception ex) {
ex.printStackTrace();
throw new InterruptedException(ex.getMessage());
}
}
- FutureTask extends Runnable, Callable
- result.get 会阻塞等待结果
- cache.putIfAbsent(); 没有则添加,避免多线程下面可能引发的问题.
- ConcurrentHashMap的锁机制是针对Node节点
- Collections.synchronizedMaps()的锁是对象锁.并发性的话ConcurrentHashMap要好很多!
- Collections.synchronizedMaps遍历时需加对象锁,否则会报ConcurrentXXX错误.