如何配置番石榴缓存以在读取后删除项目?

How to configure guava cache to remove item after a read?

我想在从缓存中读取项目后将其删除(使其失效)。

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

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

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

在我的示例中,随机数创建了两次:

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" 打印了两次。

这行不通。 "Access" 表示 "read or write access" 读取后立即过期,写入后也会立即过期。

您可以手动删除条目。您可以使用 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 永远不应该重复,我想不出有什么理由存储它们。通常,您会立即生成并使用它们。

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

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

 Object cachedValue = cache.asMap().remove(key);