带有过期的不可变集合

Kat*_*yA. 3 java guava

我在做什么:我正在收集一个潜在的大型对象集合,并要求用户根据集合进行输入.我想缓存对象以避免重新获取它们,但我希望收集在短时间后过期,以防用户散失.如果需要,我会重新获取对象.该集合不会在所涉及的短时间内发生变化.

我看过的内容:由于基于时间的过期,Guava的Cache看起来很有希望.然而,有几件事让我感到困扰.我真的不需要地图 - 集合将被完整访问或根本不访问.而且我担心我会遇到竞争条件,当我访问缓存时,缓存中的项目开始到期.这增加了一定程度的复杂性,必须跟踪我的所有项目是否都在缓存中,从而消除了缓存的一些价值.

我的问题:如果我不是将单个项目放在缓存中,而是将它们放入一个Guava ImmutableCollection并将其放入缓存中,我是否会遇到麻烦?这似乎是我一次访问整个集合的方式,并且集合在缓存中或者不在(在这种情况下我重建它).我没有看到这种方法存在的缺陷吗?

Mar*_*ers 5

为Guava缓存提供静态单例密钥并不罕见. Cache即使不用作时,也能提供很多好处Map.我会做这样的事情:

 private static final Object CACHE_KEY = new Object();

 private LoadingCache<Object, List<SomeType>> cache = 
      CacheBuilder.newBuilder()
        .expireAfterWrite(5, TimeUnit.MINUTES)
        .softValues()
        .build(valuesLoader());

 //...
 List<SomeType> values = cache.get(CACHE_KEY);
Run Code Online (Sandbox Code Playgroud)

在我的代码库中,我在一些地方使用具有单个值的缓存,因此我将SingleValueLoadingCache<T>其抽象为暴露无法get()方法并封装缓存和密钥.

这似乎是我一次访问整个集合的方式,并且集合在缓存中或者不在(在这种情况下我重建它).我没有看到这种方法存在的缺陷吗?

如果你还没有找到它,你可能想要一个LoadingCache通过传递CacheLoader到的build方法CacheBuilder.这样你就可以随时调用get(),如果该值不在缓存中,则会使用CacheLoader您提供的内容自动和同步地为您加载.

  • 超级小的nit,但我只是使用`Object CACHE_KEY = new Object()`来确保除了那个常量匹配之外的任何东西,不像可能来自任意数量的不同位置的空字符串. (2认同)