【问题标题】:Guava cache expireAfterAccess issueGuava 缓存 expireAfterAccess 问题
【发布时间】:2017-01-31 11:25:28
【问题描述】:

我有一个问题。如果我使用 expireAfterAccess 并假设我的条目在 2 小时后过期。现在,如果我在一段时间后(比如 5 小时)为该条目调用 get(),它会再次被缓存吗?还是会永久过期?

private final LoadingCache<String, Map<String, PinPointRule>> pinPointRuleCache = CacheBuilder.newBuilder().maximumSize(500000)
        .expireAfterAccess(2, TimeUnit.HOURS).build(new CacheLoader<String, Map<String, PinPointRule>>(){
            @Override
            public Map<String, PinPointRule> load(String dummyToken) throws Exception {
                return loadPinPointRules(dummyToken);
            }

            public ListenableFuture<Map<String,PinPointRule>> reload(final String key, final Map<String,PinPointRule> oldValue) throws Exception {
                ListenableFutureTask<Map<String,PinPointRule>> task = ListenableFutureTask.create(new Callable<Map<String,PinPointRule>>() {
                    public Map<String,PinPointRule> call() throws Exception {
                        long start = System.nanoTime();
                        LOGGER.info("LoadingCache Reload");
                        try {
                            return loadPinPointRules(key);
                        } catch (Exception e) {
                            LOGGER.error("Error while loading pinpoint rules. Returning old value. Exception :: {}", getStackTrace(e));
                        } finally {
                            LOGGER.info("Time taken in reloading pinpoint rule: {} ", TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
                        }
                        return oldValue;
                    }
                });
                executor.execute(task);
                return task;
            };
        });

【问题讨论】:

  • 它会再次被缓存(即您提供的CacheLoader 上的load 方法将被调用),这就是缓存的工作方式。
  • @Xaerxess:谢谢,我无法通过文档获取此信息。

标签: java caching guava google-guava-cache


【解决方案1】:

作为Xaerxess commented,“它将再次被缓存(即,将调用您提供的 CacheLoader 上的加载方法),这就是缓存的工作方式。”

当有疑问并且文档不够清晰时,您可以随时对其进行测试:

@Test
public void expireAfterAccessReloadsCache() throws Exception {
    CacheLoader<Integer, String> cacheLoader = Mockito.mock(CacheLoader.class);
    Integer testKey = 1;
    String testValue = "1";
    when(cacheLoader.load(testKey)).thenReturn(testValue);
    FakeTicker fakeTicker = new FakeTicker();
    LoadingCache<Integer, String> loadingCache = CacheBuilder.newBuilder()
            .ticker(fakeTicker)
            .expireAfterAccess(2, TimeUnit.HOURS)
            .build(cacheLoader);
    assert testValue.equals(loadingCache.get(testKey));
    verify(cacheLoader).load(testKey);
    assert testValue.equals(loadingCache.get(testKey));
    verifyZeroInteractions(cacheLoader);
    fakeTicker.advance(1, TimeUnit.HOURS);
    assert testValue.equals(loadingCache.get(testKey));
    verifyZeroInteractions(cacheLoader);
    fakeTicker.advance(4, TimeUnit.HOURS);
    assert testValue.equals(loadingCache.get(testKey));
    verify(cacheLoader, times(2)).load(testKey);
    assert testValue.equals(loadingCache.get(testKey));
    verifyZeroInteractions(cacheLoader);
}

这当然不是你会在测试中使用的东西,但这种类型的练习对于更好地理解库的工作原理非常有用。

您还可以通过阅读/单步执行其单元/功能测试来了解课程的工作原理。例如guava/CacheExpirationTest.java at master · google/guava.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    相关资源
    最近更新 更多