我使用番石榴缓存支持为测试缓存过期编写了以下代码。在下面的代码中,我创建了一个缓存,从键 11000 到 30000 添加 20 个条目,经过一些休眠遍历缓存中存在键并搜索两个键(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 个问题
- 为什么其他类似 17000,19000,25000 的密钥没有在 RemovalListener 中通知
- 为什么缓存键集上的迭代为空,而缓存大小为 12
- 为什么在缓存大小为 12 时搜索 19000 和 29000 为空