java同步缓存上的批量操作
我想实现一个简单的缓存,它会定期更新,每次更新都会触发完全缓存清除和数据插入 伪代码:java同步缓存上的批量操作,java,multithreading,caching,Java,Multithreading,Caching,我想实现一个简单的缓存,它会定期更新,每次更新都会触发完全缓存清除和数据插入 伪代码: //context calls periodically this method cache.clear(); cache.putAll(newValues) 因为其他线程可能在刷新操作期间读取缓存。我需要某种同步 最简单的解决方案可能与以下类似: computeNewCacheValues() computeStaleKeys() //e.g. ones are in the cache but are
//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实例支持-因此在缓存更新期间:
- 没有出现并发问题(?)
- 缓存在整个进程中未锁定(因此在刷新期间可访问)
这可能是一个很好的解决方案,但我想知道:有没有其他更有效/安全的方法来实现这一点?是否有能够执行此操作的库?如果您总是更换整个缓存,您可以直接更换它
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);
}
final AtomicReference mapRef=新的AtomicReference();
//假设调用此函数后不修改映射。
公共空间更新(地图){
mapRef.set(map);
}
公共V get(K键){
//这将始终看到最新的完整地图。
返回mapRef.get().get(键);
}
注意:无需锁定,因为地图添加到缓存后不会更改。供将来参考:
创建“大容量缓存”
”时,最简单的解决方案可能是@Peter提到的解决方案;在单独的线程上创建新缓存,并将旧缓存的引用更改为新缓存
需要考虑的事项:
- 该解决方案是有效的,因为赋值运算符(“
”)的执行是原子的=
- 缓存对象必须是易变的;这样,它的值就可以被多个线程访问(没有这个线程,一个线程可能会更改它的值,但是另一个线程将无法看到更改)
是另一个选项;基本上它是一个易失性对象的包装器,尽管它添加了一些有用的方法(例如用于审计)AtomicReference
volatile
时,不涉及锁定,您可以安全地拥有任意数量的并发读卡器。在这种情况下,您可以使用一个简单的volatile Map
。谢谢您的回答!