use*_*887 7 java multithreading synchronization caching double-checked-locking
我有一个人们要求资源的网络应用程序.为了提高效率,使用同步哈希映射缓存此资源.这里的问题是当同时为同一个未缓存的资源发出两个不同的请求时:检索资源的操作会占用大量内存,所以我想避免为同一个资源多次调用它.
有人可以告诉我,以下代码段是否存在任何潜在问题?提前致谢.
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);
}
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
一个可能的问题是您通过veryCostlyOperation()在synchronized块内执行来创建不必要的争用,因此许多线程无法同时检索其(独立)资源.这可以通过使用Future<Resource>map的值来解决:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5149 次 |
| 最近记录: |