gpt4 book ai didi

java - Guava 缓存 api 中的 RemovalListener 回调无法正常工作

转载 作者:行者123 更新时间:2023-11-29 05:37:06 25 4
gpt4 key购买 nike

我使用 Guava 缓存支持编写以下代码来测试缓存过期。在下面的代码中,我创建了一个缓存,从键 11000 到 30000 向其中添加了 20 个条目,经过一些 sleep 遍历后缓存中存在键并搜索两个键(19000 和 29000)

import com.google.common.cache.*;
import java.util.concurrent.TimeUnit;

public class TestGuavaCache {

public static int evictCount = 0;

public static void main(String[] args) throws InterruptedException {

Cache<Integer, Record> myCache = CacheBuilder.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS)
.expireAfterWrite(15, TimeUnit.SECONDS)
.concurrencyLevel(4)
.maximumSize(100)
.removalListener(new RemovalListener<Object, Object>() {
@Override
public void onRemoval(RemovalNotification<Object, Object> notification) {
evictCount++;
System.out.println(evictCount + "th removed key >> " + notification.getKey()
+ " with cause " + notification.getCause());
}
})
.recordStats()
.build();

int nextKey = 10000;

for (int i = 0; i < 20; i++) {

nextKey = nextKey + 1000;

myCache.put(nextKey, new Record(nextKey, i + " >> " + nextKey));

Thread.sleep(1000);
}

System.out.println("=============================");
System.out.println("now go to sleep for 20 second");

Thread.sleep(20000);

System.out.println("myCache.size() = " + myCache.size());

for (Integer key : myCache.asMap().keySet()) {
System.out.println("next exist key in cache is" + key);
}
System.out.println("search for key " + 19000 + " : " + myCache.getIfPresent(19000));
System.out.println("search for key " + 29000 + " : " + myCache.getIfPresent(29000));
}
}

class Record {

int key;
String value;

Record(int key, String value) {
this.key = key;
this.value = value;
}

}

运行上面的主要方法后,我看到以下结果

1th removed key >> 11000 with cause EXPIRED
2th removed key >> 13000 with cause EXPIRED
3th removed key >> 12000 with cause EXPIRED
4th removed key >> 15000 with cause EXPIRED
5th removed key >> 14000 with cause EXPIRED
6th removed key >> 16000 with cause EXPIRED
7th removed key >> 18000 with cause EXPIRED
8th removed key >> 20000 with cause EXPIRED
=============================
now go to sleep for 20 second
myCache.size() = 12
search for key 19000 : null
search for key 29000 : null

我有3个问题

  1. 为什么别人key类似17000,19000,25000没有通知移除监听器
  2. 为什么缓存键集上的迭代在缓存时为空尺寸为 12
  3. 为什么在缓存大小时搜索 19000 和 29000 为空是 12

最佳答案

直接来自 Javadocs:

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 by Cache.size(), but will never be visible to read or write operations.

一旦到期时间过去,Guava 的缓存不会立即清理条目;这是因为它(有意地)不创建一个额外的线程来维护缓存。经常对各种查询操作执行清理。特别是,上述文档解释了 size() 方法可能会暂时计算过期的条目。

关于java - Guava 缓存 api 中的 RemovalListener 回调无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19092790/

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