Hac*_*und 4 java guava google-guava-cache
我有一个这样的加载缓存:
MyCacheLoader loader=new MyCacheLoader();
MyRemovalListener listener=new MyRemovalListener();
LoadingCache<String, String> myCache = CacheBuilder.newBuilder()
.concurrencyLevel(10)
.weakKeys()
.maximumSize(2)
.expireAfterWrite(120, TimeUnit.SECONDS)
.removalListener(listener)
.build(loader);
Run Code Online (Sandbox Code Playgroud)
但是当我做这样的事情来测试时:
System.out.println(myCache.get("100"));
System.out.println(myCache.get("103"));
System.out.println(myCache.get("110"));
System.out.println(myCache).get("111"));
Thread.sleep(230000);
System.out.println(myCache.size());
Run Code Online (Sandbox Code Playgroud)
我仍然得到 2 而不是零。为什么 ?超过 120 秒后,如果我没有错的话,我的大小应该为零吗?
我的缓存加载器
public class MyCacheLoader extends CacheLoader<String,String> {
@Override
public String load(String key) throws Exception {
return key;
}
}
Run Code Online (Sandbox Code Playgroud)
我的移除监听器
public class MyRemovalListener implements RemovalListener<String,String> {
Logger logger = LoggerFactory.getLogger(MyRemovalListener.class);
@Override
public void onRemoval(RemovalNotification<String, String> removalNotification) {
logger.info("Message with message Id ("+
removalNotification.getKey()+ ") is removed.");
System.out.println("Message with message Id ("+
removalNotification.getKey()+ ") is removed.");
}
}
Run Code Online (Sandbox Code Playgroud)
首先,如果您不熟悉 Guava 的缓存 API,或者您将其视为实现了Map<K, V>接口,那么我建议您阅读CachesExplained · google/guava Wiki。“ACache类似于ConcurrentMap,但不完全相同。”
例如,Cache.size()“返回此缓存中条目的近似数量”(添加强调)与Map.size()“返回此映射中的键值映射数”不同。
因此,我们不应期望Cache.size()返回确切数量的条目,而是返回近似数量的条目。我一般不会断言,Cache.size()虽然我肯定会Map.size()。
其次,“配建高速缓存CacheBuilder也没有执行清理和逐出值‘自动’或价值期满后即刻,或诸如此类的事,而是在写操作期间执行少量维修期间,或写是偶尔读操作罕见”(什么时候清理?·CachesExplained·google/guava Wiki)。
考虑以下示例:
LoadingCache<String, String> myCache = CacheBuilder.newBuilder()
.concurrencyLevel(10)
.weakKeys()
.maximumSize(2)
.expireAfterWrite(120, TimeUnit.MILLISECONDS)
.removalListener(notification ->
System.out.println(notification.getKey() + " removed"))
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
System.out.println("loading " + key);
return UUID.randomUUID().toString();
}
});
myCache.get("100");
myCache.get("103");
myCache.get("110");
myCache.get("111");
Thread.sleep(230);
System.out.println(myCache.size());
myCache.get("111");
System.out.println(myCache.size());
Run Code Online (Sandbox Code Playgroud)
输出:
LoadingCache<String, String> myCache = CacheBuilder.newBuilder()
.concurrencyLevel(10)
.weakKeys()
.maximumSize(2)
.expireAfterWrite(120, TimeUnit.MILLISECONDS)
.removalListener(notification ->
System.out.println(notification.getKey() + " removed"))
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
System.out.println("loading " + key);
return UUID.randomUUID().toString();
}
});
myCache.get("100");
myCache.get("103");
myCache.get("110");
myCache.get("111");
Thread.sleep(230);
System.out.println(myCache.size());
myCache.get("111");
System.out.println(myCache.size());
Run Code Online (Sandbox Code Playgroud)
如您所见,在从缓存中读取项目之前,不会发生驱逐。
有关更多详细信息以及更详细的示例,请参阅我对定时缓存到期如何工作的回答?
| 归档时间: |
|
| 查看次数: |
3113 次 |
| 最近记录: |