【问题标题】:Guava LoadingCache loads new value everytime for same keyGuava LoadingCache 每次都为同一个键加载新值
【发布时间】:2014-12-17 20:54:23
【问题描述】:

我正在使用 Guava LoadingCache 来存储来自数据库查询的结果。但是,尽管没有设置驱逐策略,但通过 getFromCache() 获取缓存会导致我在 CacheLoader load() 方法中的调试点每次都被命中,因此也会在数据库查询方法 getKeyFromDatabase() 中产生一个调试点每次都被击中。

这是我的代码:

private final LoadingCache<String, QueryResult> cache;

public MyDao() {
    cache = CacheBuilder.newBuilder()
        .maximumSize(40)
        .build(new CacheLoader<String, QueryResult>() {
            @Override
            public QueryResult load(String key) throws DatabaseException {
                return getKeyFromDatabase(key);
            }
        });
}

public QueryResult getFromCache(String key) throws DatabaseException {
    try {
        return cache.get(key);
    } catch (ExecutionException e) {
        throw new DatabaseException(e);
    }
}

private QueryResult getKeyFromDatabase(String key) throws DatabaseException {
    try {
        ...
        return new QueryResult();
    } catch (SQLException e) {
        throw new DatabaseException(e);
    }
}

我在这里遗漏了什么明显的东西吗?

【问题讨论】:

  • 该代码无法编译,是吗? (.getFromCache())
  • 另外,请在您的CacheLoader 中指定比Exception 更具体的例外;当你实现一个抛出某些东西的方法时,你可以将抛出的异常更改为给定异常的任何子类。
  • 是的,我对异常处理很好奇...如果getKeyFromDatabase 每次都抛出一个异常并且这个事实以某种方式对你隐藏,它将不得不继续尝试再次加载每次。
  • 我编辑了我的帖子,添加了例外。我一步步通过getKeyFromDatabase()和load()和getFromCache(),没有抛出异常,每次都是从数据库加载。
  • 我也尝试在构建器中设置一个 .expireAfterWrite(10, TimeUnit.MINUTES) ,但它仍然每次都针对同一个键点击加载方法。

标签: java caching guava


【解决方案1】:

好吧,假警报,番石榴实际上并没有坏掉(惊喜惊喜)。原因是因为每次实例化DAO的代码都在实例化一个新对象,所以每次也实例化一个新的缓存。我将缓存设置为静态变量,现在它可以工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-09
    • 2021-08-17
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2013-04-24
    相关资源
    最近更新 更多