Java 如何配置guava缓存以在读取后删除项?

Java 如何配置guava缓存以在读取后删除项?,java,caching,guava,google-guava-cache,evict,Java,Caching,Guava,Google Guava Cache,Evict,我想在从缓存中读取项目后将其删除(使其无效) 所以在第一次读取之前,项应该存在于缓存中 我已尝试添加expireAfterAccess(0,TimeUnit.NANOSECONDS),但缓存未填充 有没有办法以这种方式使用guava缓存,或者我需要在读取后手动使项无效?在我的示例中,nonce创建两次: LoadingCache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(0, TimeUni

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

所以在第一次读取之前,项应该存在于缓存中

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


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

在我的示例中,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;
}
LoadingCache cache=CacheBuilder.newBuilder().expireAfterAccess(0,时间单位。纳秒)
.build(新的缓存加载程序(){
@凌驾
公共字符串加载(字符串键)引发异常{
返回createNonce();
}
});
@试验
public void test_cache_execution()引发异常{
字符串nonce1=cache.getUnchecked(“key”);
字符串nonce2=cache.getUnchecked(“key”);
}
公共字符串createNonce(){
字符串createdNonce=“createdNonce”;
System.out.println(creatednone);
返回creatednone;
}

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

在我的示例中,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;
}
LoadingCache cache=CacheBuilder.newBuilder().expireAfterAccess(0,时间单位。纳秒)
.build(新的缓存加载程序(){
@凌驾
公共字符串加载(字符串键)引发异常{
返回createNonce();
}
});
@试验
public void test_cache_execution()引发异常{
字符串nonce1=cache.getUnchecked(“key”);
字符串nonce2=cache.getUnchecked(“key”);
}
公共字符串createNonce(){
字符串createdNonce=“createdNonce”;
System.out.println(creatednone);
返回creatednone;
}
在日志中,“CreatedOnce”打印两次。

这不起作用。“访问”是指“读或写访问”,当它在读取后立即过期时,也会在写入后立即过期

您可以手动删除该条目。您可以使用
asMap()
视图在一次访问中执行此操作:

String getAndClear(String key) {
    String[] result = {null};    
    cache.asMap().compute(key, (k, v) ->
        result[0] = v;
        return null;
    });
    return result[0];
}
你可以改用咖啡因,这是一种更高级的番石榴贮藏,提供非常灵活的饮料

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

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

这行不通。“访问”是指“读或写访问”,当它在读取后立即过期时,也会在写入后立即过期

您可以手动删除该条目。您可以使用
asMap()
视图在一次访问中执行此操作:

String getAndClear(String key) {
    String[] result = {null};    
    cache.asMap().compute(key, (k, v) ->
        result[0] = v;
        return null;
    });
    return result[0];
}
你可以改用咖啡因,这是一种更高级的番石榴贮藏,提供非常灵活的饮料

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


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

get and remove操作是地图界面上的一个简单的
remove

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

获取和删除操作是地图界面上的一个简单的
remove

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

如果要在访问后立即失效,为什么需要缓存?@OleksandrBondarchuk我需要在一定时间(例如15分钟)后过期的条目,并且在读取后应立即处理这些条目。我想存储nonce-如果要在访问后立即失效,为什么需要缓存?@OleksandrBondarchuk我需要在一定时间段(例如15分钟)后过期的条目,并且在读取后应立即处理这些条目。我想存储nonces——嗨,Google的SafetyNet实现中有这样的nonces。电话请求一个nonce,然后发送服务器验证的JWT令牌-此时您应该验证JWT令牌是否包含先前请求的nonce。请参阅:@pixel我在那里看到“WebService为会话存储nonce”,但我看不到任何加载。无论如何,我更新了我的答案。+1为此目的不使用
缓存
——您应该在需要执行的工作开始时生成nonce,然后在完成时让它过期(通过超出范围并被GCed)。15分钟的有效期只是为了防止您提出长时间或延迟的请求,实际上,您不应该为任何接近有效期限制的事情保留这样一个临时值。您好,Google的SafetyNet实现中存在这种临时值的情况。电话请求一个nonce,然后发送服务器验证的JWT令牌-此时您应该验证JWT令牌是否包含先前请求的nonce。请参阅:@pixel我在那里看到“WebService为会话存储nonce”,但我看不到任何加载。无论如何,我更新了我的答案。+1为此目的不使用
缓存
——您应该在需要执行的工作开始时生成nonce,然后在完成时让它过期(通过超出范围并被GCed)。15分钟的有效期只是为了防止您提出长时间或延迟的请求,实际上,对于任何接近有效期限制的事情,您都不应该保留这样一个临时值。