14

我需要经常访问耗时计算的结果。结果不经常变化,所以我不得不时不时地重新计算数据,但暂时使用过时的结果是可以的。最简单的方法是什么?是否有现有的库方法或设计模式?

我在想类似的东西

private static List myCachedList = null;

...

// refresh list once in 3600 seconds
if (needsRefresh(myCachedList, 3600)) {
    // run the calculation
    myCachedList = ...
}
// use either updated or previous value from here on

一个正确的实现可能不是微不足道的,它可能必须处理线程安全、竞争条件等,所以我宁愿使用一个经过验证的实现而不是在这里推出我自己的实现。

4

5 回答 5

21

恭喜您意识到编写自己的代码可能会更麻烦!

我会查看Guava 缓存解决方案。Guava 是一个经过验证的库,缓存可以通过流畅的工厂 API 轻松获得(并且可配置)。

所有 Guava 缓存,无论是否加载,都支持 get(K, Callable<V>) 方法。此方法返回与缓存中的键关联的值,或从指定的 Callable 计算它并将其添加到缓存中。在加载完成之前,不会修改与此缓存关联的可观察状态。此方法提供了对传统“如果缓存,则返回;否则创建,缓存并返回”模式的简单替代。

于 2012-10-31T13:06:53.277 回答
3

我会看看 Google guava-libraries。大部分工作已经为您完成。

有一个专门称为 Timed Eviction 的部分,可能与您想要的有关。 https://github.com/google/guava/wiki/CachesExplained#timed-eviction

于 2012-10-31T13:06:57.513 回答
3

我建议您使用代理设计模式,这样您就可以在代理类中封装缓存逻辑实现

这里有一个很酷的例子,看起来很适合您的需求

http://en.wikipedia.org/wiki/Proxy_pattern

于 2012-10-31T13:08:59.463 回答
0

如果您不想使用第三方库,只需创建一个包含键和值的静态映射。使用密钥可以快速检索数据。

并编写方法以将值添加到缓存、获取、删除。

public SimpleCache{
    private static Map<String,Object> simpleCache = new HashMap<>();

    public static <T> T getValue(String key, Class type){

    //todo check contains here, if map doesn't contains key, throw not found exception

    Object val = simpleCache.get(key);

    return (T)val;    
  }
}

希望这可以帮助

于 2017-02-28T11:16:27.237 回答
0

您可以尝试SimplCache,它接受缓存数据库和持久数据库的实现,为缓存系统提供简单的实现。

于 2020-07-12T14:55:59.027 回答