gpt4 book ai didi

java - 尽管条目被删除,Guava CacheBuilder Cache RemovalListener onRemoval 不会每次都被调用

转载 作者:搜寻专家 更新时间:2023-10-31 19:34:21 24 4
gpt4 key购买 nike

我已经创建了一个基于 Guava CacheBuilder 的缓存,如果未写入 key ,缓存将在 5 秒内到期。向其添加了一个 removalListener,它打印被删除的键/值对。我观察到的是监听器的 onRemoval 方法仅在第一次被调用。第二次删除条目时不会调用它。 (实际删除发生了。只是 removalListener 的 onRemoval 方法没有被调用)。

我做错了什么吗?有人可以帮忙吗?提前致谢。这是我的代码:

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;


public class TestCacheBuilder {

public static void main(String[] args) {
try {
new TestCacheBuilder();
}catch (Exception e){
e.printStackTrace();
}
}

public TestCacheBuilder() {

Cache<String, String> myCache = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.SECONDS)
.removalListener(new RemovalListener<String, String>() {
public void onRemoval(RemovalNotification<String, String> removal) {
System.out.println("removal: "+removal.getKey()+"/"+removal.getValue());
}
})
.build();


Map<String, String> inMap = myCache.asMap();

inMap.put("MyKey", "FirstValue");

System.out.println("Initial Insert: "+inMap);

//Wait 16 seconds

try {
Thread.sleep(4000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}

System.out.println("After 4 seconds: " + inMap);

inMap.put("MyKey", "SecondValue");

try {
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}

System.out.println("After 1 more second: " + inMap);

try {
Thread.sleep(4000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}


System.out.println("After 4 more seconds: " + inMap);

}

}

输出如下:

Initial Insert: {MyKey=FirstValue}
After 4 seconds: {MyKey=FirstValue}
removal: MyKey/FirstValue
After 1 more second: {MyKey=SecondValue}
After 4 more seconds: {}

最佳答案

删除实际上并没有直接发生:Guava 没有自己的清理线程来删除过期的条目。删除通常发生在缓存的同一段中有写入时,或者在经过一定时间后的读取期间(以分摊删除成本)。然而,虽然该条目仍然存在,但它被视为已过期,这就是它未被打印的原因。

引用 CacheBuilder's javadoc :

If expireAfterWrite or expireAfterAccess is requested entries may be evicted on each cache modification, on occasional cache accesses, or on calls to Cache.cleanUp(). Expired entries may be counted in Cache.size(), but will never be visible to read or write operations.

关于java - 尽管条目被删除,Guava CacheBuilder Cache RemovalListener onRemoval 不会每次都被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12157014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com