在LoadingCache中更改映射值

时间:2014-04-09 09:22:59

标签: guava

缓存支持在本地和后端频繁更改的地图。我使用AtomicLong作为地图值类型。当我想更改缓存地图中的值时,我在下面执行了此操作

    private static final LoadingCache<String, Map<Integer, AtomicLong>> NWZs = CacheBuilder.newBuilder()
    private void incNWZ(String word, Integer topic, int delta) throws ExecutionException {
        Map<Integer, AtomicLong> wincm = NWZs.get(word);
        if (!wincm.containsKey(topic)) {
            wincm.put(topic, new AtomicLong(0));
        }
        wincm.get(topic).addAndGet(delta);
    }

我的问题是,如果我调用incNWZ,下次读取时缓存中的值是否会更改?

2 个答案:

答案 0 :(得分:1)

以下代码显示它将起作用

private static final LoadingCache<String, Map<Integer, AtomicLong>> NWZs = CacheBuilder.newBuilder()
        .weakKeys()
        .weakValues()
        .expireAfterWrite(60, TimeUnit.MINUTES)
        .expireAfterAccess(20, TimeUnit.MINUTES)
        .build(
                new CacheLoader<String, Map<Integer, AtomicLong>>() {
                    @Override
                    public Map<Integer, AtomicLong> load(String word) throws Exception {
                        Map<Integer, AtomicLong> map = new HashMap<>();
                        map.put(0, new AtomicLong(10));
                        return map;
                    }
                });

public static void main(String[] args) throws Exception {
    System.out.println(NWZs.get("foo").get(0));
    Map<Integer, AtomicLong> wincm = NWZs.get("foo");
    wincm.get(0).addAndGet(5);
    System.out.println(NWZs.get("foo").get(0));
}

输出应为

10
15

答案 1 :(得分:1)

它会,假设

  • 由于缓存中没有wincm,您无法获得NPE
  • 您修改后的Map不会被驱逐并重新加载

我想第二种情况还可以,因为我希望你修改缓存值和它们来自的原始数据。但是有一些有趣的问题,比如

  • 您尝试更新缓存中的数据并且它不存在(所以您认为它很好)
  • 数据在
  • 之前加载到缓存中
  • 您在后端更新它们

或反过来

  • 您更新后端的数据
  • 并将它们加载到缓存中
  • 然后再次手动更新