Java 迭代番石榴加载缓存';s地图视图条目集是否重置用于过期的访问时间?
我使用以下方法创建了一个: 这会更新缓存中每个条目的访问时间吗?我已经仔细阅读了JavaDoc,但发现它在本例中不明确: 指定在条目创建、最近一次替换其值或最后一次访问后经过固定的持续时间后,应自动从缓存中删除每个条目。访问时间由所有缓存读写操作(包括Java 迭代番石榴加载缓存';s地图视图条目集是否重置用于过期的访问时间?,java,guava,Java,Guava,我使用以下方法创建了一个: 这会更新缓存中每个条目的访问时间吗?我已经仔细阅读了JavaDoc,但发现它在本例中不明确: 指定在条目创建、最近一次替换其值或最后一次访问后经过固定的持续时间后,应自动从缓存中删除每个条目。访问时间由所有缓存读写操作(包括cache.asMap().get(Object)和cache.asMap().put(K,V))重置,但不由cache.asMap的集合视图上的操作重置 显然,我提到的第二种迭代方法确实重置了访问时间,但我想知道使用第一种方法的行为是什么。我将解
cache.asMap().get(Object)
和cache.asMap().put(K,V)
)重置,但不由cache.asMap
的集合视图上的操作重置
显然,我提到的第二种迭代方法确实重置了访问时间,但我想知道使用第一种方法的行为是什么。我将解释如下: (…)但不是通过Cache.asMap的集合视图上的操作 请参阅
入口集
、键集
和值
。这是地图的三个集合视图。因此,使用它们不应导致访问
下面是JUnit(+Mockito)测试,它们显示了每种情况下的行为。通过entrySet
或values
读取值不会阻止条目被删除(也不会从entrySet
或keySet
读取密钥)。使用asMap().get()
进行读取,正如文档所指定的那样,确实算作访问
安装程序
键集
asMap().get()
@测试
public void testmapgetaccesscountsasasaccess(){
//写
当(ticker.read())。然后返回(TimeUnit.SECONDS.toNanos(0));
cache.put(“foo”、“bar”);
//阅读
when(ticker.read())。然后return(TimeUnit.SECONDS.toNanos(4));
cache.asMap().get(“foo”);
//维护
when(ticker.read())。然后return(TimeUnit.SECONDS.toNanos(6));
cache.cleanUp();
验证(removalListener,never()).onremovation(Mockito.any());
}
那么,你看过资料来源了吗?@NiklasB。还没有。这是漫长的一天,兔子洞现在对我来说有点深;访问时间未更新。(我保持com.google.common.cache
)极好的答案。谢谢您,@LouisWasserman感谢您根据您的特殊知识进行确认。我阅读了源代码。是的,答案是正确的。你可以在这里找到代码(asMap().get()):和这里(getValue()和getKey()):嗨,有没有办法将LoadingCache(String,List[String])作为scala集合进行迭代,例如:((k,v)对不起,我的伪prev问题,当然它可能看起来像((k,v)
LoadingCache<K,V> myCache = CacheBuilder.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES)
.maximumSize(500)
.build(someCacheLoader);
for (Map.Entry<K, V> entry : myCache.asMap().entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
doSomeWorkOn(key, value);
}
private Ticker ticker = Mockito.mock(Ticker.class);
@SuppressWarnings({"unchecked"})
private RemovalListener<String, String> removalListener = Mockito.mock(RemovalListener.class);
private Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterAccess(5, TimeUnit.SECONDS)
.removalListener(removalListener)
.ticker(ticker)
.build();
@Test
public void testEntrySetAccessDoesNotCountAsAccess() {
//write
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(0));
cache.put("foo", "bar");
//read
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(4));
cache.asMap().entrySet().iterator().next().getValue();
cache.asMap().entrySet().iterator().next().getKey();
//maintenance
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(6));
cache.cleanUp();
verify(removalListener).onRemoval(Mockito.<RemovalNotification<String,String>>any());
}
@Test
public void testKeySetAccessDoesNotCountAsAccess() {
//write
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(0));
cache.put("foo", "bar");
//read
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(4));
cache.asMap().keySet().iterator().next();
//maintenance
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(6));
cache.cleanUp();
verify(removalListener).onRemoval(Mockito.<RemovalNotification<String,String>>any());
}
@Test
public void testValuesAccessDoesNotCountAsAccess() {
//write
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(0));
cache.put("foo", "bar");
//read
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(4));
cache.asMap().values().iterator().next();
//maintenance
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(6));
cache.cleanUp();
verify(removalListener).onRemoval(Mockito.<RemovalNotification<String,String>>any());
}
@Test
public void testMapGetAccessCountsAsAccess() {
//write
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(0));
cache.put("foo", "bar");
//read
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(4));
cache.asMap().get("foo");
//maintenance
when(ticker.read()).thenReturn(TimeUnit.SECONDS.toNanos(6));
cache.cleanUp();
verify(removalListener, never()).onRemoval(Mockito.<RemovalNotification<String,String>>any());
}