我正在实现一个简单的缓存,并将缓存存储为 AtomicReference。
private AtomicReference<Map<String, String>> cacheData;
缓存对象应该从数据库表(延迟)填充。
我提供了一种方法将缓存数据返回给调用者,但如果数据为空(即未加载),则代码需要从数据库加载数据。为了避免同步,我想到使用compareAndSet()方法:
public Object getCacheData() {
cacheData.compareAndSet(null, getDataFromDatabase()); // atomic reload only if data not set!
return Collections.unmodifiableMap(cacheData.get());
}
以这种方式使用compareAndSet可以吗?将数据库调用作为原子操作的一部分?它比仅仅同步方法更好/更差吗?
非常感谢您的任何建议..
您没有达到预期的行为。这个表达式:
cacheData.compareAndSet(null, getDataFromDatabase())
will always call getDataFromDatabase()
第一的。这意味着数据是否被缓存并不重要。如果是,您仍然调用数据库,但丢弃结果。缓存可以工作,但性能同样很差。
考虑一下这个:
if(cacheData.get() == null) {
cacheData.compareAndSet(null, unmodifiableMap(getDataFromDatabase()));
}
return cacheData.get());
它并不完美(仍然getDataFromDatabase()
可以在开始时多次调用),但稍后会按预期工作。我也搬家了Collections.unmodifiableMap()
提前,这样您就不必一遍又一遍地包装同一张地图。
这给我们带来了更简单的实现(没有synchronized
or AtomicReference
需要):
private volatile Map<String, String> cacheData;
if(cacheData == null) {
cacheData = unmodifiableMap(getDataFromDatabase());
}
return cacheData;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)