1

我想在从缓存中读取项目后删除(无效)项目。

所以项目应该存在于缓存中,直到第一次读取。

我试过添加expireAfterAccess(0, TimeUnit.NANOSECONDS),但没有填充缓存。

有没有办法以这种方式使用番石榴缓存,或者我需要在读取后手动使项目无效?

4

3 回答 3

4

这行不通。“访问”意味着“读取或写入访问”,当它在读取后立即到期时,它也在写入后立即到期。

您可以手动删除条目。您可以使用asMap()视图以便在一次访问中完成它:

String getAndClear(String key) {
    String[] result = {null};    
    cache.asMap().compute(key, (k, v) ->
        result[0] = v;
        return null;
    });
    return result[0];
}

您可以切换到 Caffeine,它是一种更高级的 Guava 缓存,并提供非常灵活expireAfter(Expiry)的 .

但是,我不认为您想要的是缓存工作。由于 nonce 永远不应该重复,我无法想象有任何理由存储它们。通常,您会立即生成并使用它们。

您可能做错了,您可能需要详细说明,以避免可能的安全问题。

于 2017-12-04T22:14:37.190 回答
0

在我的示例中,nonce 被创建了两次:

LoadingCache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(0, TimeUnit.NANOSECONDS)
    .build(new CacheLoader<String, String>() {
        @Override
        public String load(String key) throws Exception {
            return createNonce();
        }
    });

@Test
public void test_cache_eviction() throws Exception {
    String nonce1 = cache.getUnchecked("key");
    String nonce2 = cache.getUnchecked("key");
}

public String createNonce() {
    String createdNonce = "createdNonce";
    System.out.println(createdNonce);
    return createdNonce;
}

在日志中“createdNonce”被打印两次。

于 2017-12-04T21:29:18.327 回答
0

remove地图界面上的get和remove操作很简单:

 Object cachedValue = cache.asMap().remove(key);
于 2017-12-14T03:01:24.153 回答