Man*_*dyW 4 java java.util.concurrent compare-and-swap
我正在实现一个简单的缓存,缓存存储为AtomicReference.
private AtomicReference<Map<String, String>> cacheData;
Run Code Online (Sandbox Code Playgroud)
应该从数据库表中填充(延迟)缓存对象.
我提供了一种方法来将缓存数据返回给调用者,但如果数据为空(即未加载),则代码需要从数据库加载数据.为避免同步我想到使用compareAndSet()方法:
public Object getCacheData() {
cacheData.compareAndSet(null, getDataFromDatabase()); // atomic reload only if data not set!
return Collections.unmodifiableMap(cacheData.get());
}
Run Code Online (Sandbox Code Playgroud)
以这种方式使用compareAndSet是否可以.将数据库调用作为原子动作的一部分?是否比同步方法更好/更差?
非常感谢任何建议..
您没有达到预期的行为.这个表达式:
cacheData.compareAndSet(null, getDataFromDatabase())
Run Code Online (Sandbox Code Playgroud)
将始终调用getDataFromDatabase()第一.这意味着数据是否被缓存无关紧要.如果是,您仍然会调用数据库,但会丢弃结果.缓存正在运行,但性能同样差.
请考虑一下:
if(cacheData.get() == null) {
cacheData.compareAndSet(null, unmodifiableMap(getDataFromDatabase()));
}
return cacheData.get());
Run Code Online (Sandbox Code Playgroud)
它并不完美(仍然getDataFromDatabase()可以在开始时多次调用),但可以按预期工作.我也Collections.unmodifiableMap()提前移动了,所以你不必一遍又一遍地包裹同一张地图.
这使我们更简单的实施(没有synchronized或AtomicReference需要):
private volatile Map<String, String> cacheData;
if(cacheData == null) {
cacheData = unmodifiableMap(getDataFromDatabase());
}
return cacheData;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4340 次 |
| 最近记录: |