番石榴缓存expireAfterAccess问题

时间:2017-01-31 11:25:29

标签: java caching guava google-guava-cache

我有一个问题。如果我使用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;
            };
        });

1 个答案:

答案 0 :(得分:0)

作为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