【发布时间】:2011-04-07 20:47:32
【问题描述】:
假设我们的应用程序中有一个 CountryList 对象,它应该返回国家列表。国家的加载是一个繁重的操作,所以列表应该被缓存。
附加要求:
- CountryList 应该是线程安全的
- CountryList 应延迟加载(仅按需加载)
- CountryList 应该支持缓存失效
- CountryList 应该优化,因为缓存很少会失效
我想出了以下解决方案:
public class CountryList {
private static final Object ONE = new Integer(1);
// MapMaker is from Google Collections Library
private Map<Object, List<String>> cache = new MapMaker()
.initialCapacity(1)
.makeComputingMap(
new Function<Object, List<String>>() {
@Override
public List<String> apply(Object from) {
return loadCountryList();
}
});
private List<String> loadCountryList() {
// HEAVY OPERATION TO LOAD DATA
}
public List<String> list() {
return cache.get(ONE);
}
public void invalidateCache() {
cache.remove(ONE);
}
}
你怎么看?你看到它有什么不好的地方吗?还有其他方法吗?我怎样才能让它变得更好?在这种情况下,我应该寻找另一种解决方案吗?
谢谢。
【问题讨论】:
-
我不相信这是线程安全的。如果两个线程同时调用 invalidateCache() 或者一个线程同时调用 list() 另一个线程调用 invalidateCache() 怎么办?
-
MapMaker 返回 Map 接口的线程安全实现。 makeComputingMap() 以原子方式进行计算 (google-collections.googlecode.com/svn/trunk/javadoc/com/google/…)
-
您要接受答案吗?
-
@Gareth Davis,我已经接受了我自己的答案。
-
Integer.valueOf(1)获取密钥的缓存版本。
标签: java caching lazy-loading