我想实现一个简单的缓存,它会定期更新,每次更新都会触发一个完整的缓存清除和数据插入。
伪代码:
//context calls periodically this method
cache.clear();
cache.putAll(newValues)
由于其他线程可能在刷新操作期间读取缓存。我需要某种同步。
最简单的解决方案可能类似于以下内容:
computeNewCacheValues()
computeStaleKeys() //e.g. ones are in the cache but are not in the new cache
removeStaleKeysOneByOneFromCache()
updateKeysFromNewCacheValueOneByOne()
实现由ConccurentHashMap实例支持 - 因此在缓存更新期间:
这可能是(?)一个很好的解决方案,但我想知道:还有其他更有效/更安全的方法来实现吗?有没有能够进行此操作的库?
答案 0 :(得分:2)
如果您总是更换整个缓存,则可以替换它。
final AtomicReference<Map<K, V>> mapRef = new AtomicReference<>();
// assuming you don't modify the map after calling this.
public void update(Map<K, V> map) {
mapRef.set(map);
}
public V get(K key) {
// this will always see the latest complete map.
return mapRef.get().get(key);
}
注意:不需要锁定,因为一旦将Map添加到缓存中,Map就不会被更改。
答案 1 :(得分:0)
供将来参考:
创建“bulk cache
”时,最简单的解决方案可能是@Peter提到的解决方案;在一个单独的线程上创建新的缓存,并将旧的缓存的引用更改为新的缓存。
需要考虑的事项:
=
”)执行是原子的volatile
;这样它的值可以被多个线程访问(没有这个线程可能会改变它的值,但是另一个线程将无法看到更改)AtomicReference
是另一种选择;基本上它是一个volatile对象的包装器,虽然它增加了一些有用的方法(例如用于审计)