我有一个网络应用程序,人们可以在其中请求资源。为了提高效率,这些资源使用同步哈希图进行缓存。这里的问题是,当两个不同的请求同时针对同一未缓存的资源时:检索资源的操作会占用大量内存,因此我想避免对同一资源多次调用它。
有人可以告诉我以下代码片段是否存在任何潜在问题吗?提前致谢。
private Map<String, Resource> resources = Collections.synchronizedMap(new HashMap<String, Resource>());
public void request(String name) {
Resource resource = resources.get(name);
if (resource == null) {
synchronized(this) {
if (resources.get(name) == null) {
resource = veryCostlyOperation(name); // This should only be invoked once per resource...
resources.put(resource);
} else {
resource = resources.get(name);
}
}
}
...
}
一个可能的问题是您通过执行创建了不必要的争用veryCostlyOperation()
里面一个synchronized
阻塞,因此许多线程无法同时检索其(独立)资源。这可以通过使用来解决Future<Resource>
作为地图的值:
Map<String, Future<Resource>> map = new ConcurrentHashMap<String, Future<Resource>>();
...
Future<Resource> r = map.get(name);
if (r == null) {
FutureTask task = null;
synchronized (lock) {
r = map.get(name);
if (r == null) {
task = new FutureTask(new Callable<Resource>() {
public Resource call() {
return veryCostlyOperation(name);
}
});
r = task;
map.put(name, r);
}
}
if (task != null) task.run(); // Retrieve the resource
}
return r.get(); // Wait while other thread is retrieving the resource if necessary
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)