SiB*_*SiB 9 java locking concurrenthashmap reentrantreadwritelock
Java大师,
目前我们有一个经常HashMap<String,SomeApplicationObject>被阅读和偶尔修改的问题,我们遇到的问题是在修改/重新加载期间,Read操作返回null是不可接受的.
要解决这个问题,我有以下选择:
这看起来像是第一选择,但我们所谈论的操作是reload()- 手段clear()紧随其后replaceAll().因此,如果Map是post clear()和pre,replaceAll()则返回null,这是不可取的.即使我synchronize这不解决问题.
B.基于ReentrantReadWriteLock创建另一个实现
在操作Write Lock之前我会在哪里创建获得reload().这似乎更合适,但我觉得必须有一些已经可用的东西,我不需要重新发明轮子.
什么是最好的出路?
编辑任何收藏已经有这样的功能吗?
这听起来很多像番石榴的 Cache,但它确实取决于你如何填充地图,以及如何计算值.(披露:我向番石榴捐款.)
真正的问题是,您是否可以指定如何计算SomeApplicationObject给定的输入String.根据你到目前为止告诉我们的内容,它可能看起来像这样......
LoadingCache<String, SomeApplicationObject> cache = CacheBuilder.newBuilder()
.build(
new CacheLoader<String, SomeApplicationObject>() {
public SomeApplicationObject load(String key) throws AnyException {
return computeSomeApplicationObject(key);
}
});
Run Code Online (Sandbox Code Playgroud)
然后,只要您想重建缓存,就可以调用cache.invalidateAll().使用a LoadingCache,您可以调用cache.get(key),如果它还没有计算出值,它将被重新计算.或调用之后,也许cache.invalidateAll(),你可以打电话cache.loadAll(allKeys),但你仍旧需要能够在同一时间,以防有任何疑问进来之间加载单一元素invalidateAll和loadAll.
如果这是不可接受的 - 如果你不能单独加载一个值,你必须一次加载它们 - 然后我继续使用Peter Lawrey的方法 - 保持volatile对地图的引用(理想情况下ImmutableMap) ,重新计算整个地图,并在完成后将新地图分配给参考.
似乎您不确定Peter Lawrey的建议如何实施。它可能看起来像这样:
class YourClass {
private volatile Map<String, SomeApplicationObject> map;
//constructors etc.
public void reload() {
Map<String,SomeApplicationObject> newMap = getNewValues();
map = Collections.unmodifiableMap(newMap);
}
}
Run Code Online (Sandbox Code Playgroud)
没有并发问题,因为:
getNewValues不需要同步或原子map原子map 是易失的,保证其他线程可以看到更改| 归档时间: |
|
| 查看次数: |
3598 次 |
| 最近记录: |