Ste*_*ood 3 java caching guava
我有一个用例,其中加载我的缓存数据的方法是批量调用,但我永远不会使用getAll从缓存中获取数据.有没有办法在一个loadAll上有多个并发获取所有块?我不希望个人使用不同的密钥导致多次调用数据源.
cache.get(key1); // missing entry, starts refresh
cache.get(key2); // separate thread, already getting reloaded due to key1 miss
Run Code Online (Sandbox Code Playgroud)
我想在查看LocalCache之后我必须实现自己的同步,在我的数据访问器中使用类似本地缓存的东西,它只允许通过每隔这么多单位时间进行调用.当调用通过时,使用单个赋值语句更新本地副本.
我是否遗漏了Guava缓存库中的内容?
编辑:
我正在考虑以下内容.但是,它可能会在loadAll完成时继续返回过时的数据.我更喜欢所有块load,只有第一个请求导致loadAll继续.
public class DataCacheLoader extends CacheLoader<String, Double>
{
private final Cache<String, Double> cache;
private ConcurrentMap<String, Double> currentData;
private final AtomicBoolean isloading;
public DataCacheLoader( final Cache<String, Double> cache )
{
this.cache = cache;
isLoading = new AtomicBoolean( false );
}
@Override
public Double load( final String key ) throws Exception
{
if ( isLoading.compareAndSet( false, true ) )
{
cache.putAll( loadAll( Lists.newArrayList( key ) ) ) );
}
return currentData.get( key );
}
@Override
public Map<String, Double> loadAll(Iterable<? extends String> keys) throws Exception
{
currentData = source.getAllData();
return currentData;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个应该解决问题的解决方案.我们的想法是,不是缓存每个单独的密钥,而是使用一个固定密钥缓存整个地图.一个缺点是您将无法使底层地图的各个部分到期(至少不容易),但这可能不是必需的.
class MyCache {
private static final Object KEY = new Object();
private final LoadingCache<Object, Map<String, Double>> delegate =
new CacheBuilder()
// configure cache
.build(new CacheLoader<Object, Map<String, Double>>() {
public Map<String, Double> load(Object key) {
return source.load();
}
};
double get(String key) {
return cache.get(KEY).get(key);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3265 次 |
| 最近记录: |