为什么timedCachetest
在最后一行失败?为什么60秒后缓存不为空?
package com.test.cache;
import java.util.concurrent.TimeUnit;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
public class CacheTest {
private static final int MAXIMUM_SIZE = 10;
private static final int CONCURRENCY_LEVEL = 1;
private static final long EXPIRE_AFTER_ACCESS = 60;
Cache<String, Thing> cache;
private static TimeUnit unit = TimeUnit.SECONDS;
private static long sec = 1000;
@Before
public void setUp() throws Exception {
cache = CacheBuilder.newBuilder().maximumSize(MAXIMUM_SIZE).concurrencyLevel(CONCURRENCY_LEVEL).expireAfterAccess(EXPIRE_AFTER_ACCESS, unit).build();
}
@After
public void tearDown() {
cache = null;
}
@Test
public void simpleCachetest() {
String key = "key";
Integer hc = key.hashCode();
Thing thing = new Thing(key);
cache.put(key, thing);
thing = cache.getIfPresent(key);
Assert.assertNotNull(thing);
Assert.assertEquals(hc, thing.getValue());
Assert.assertEquals(key, thing.getName());
Assert.assertEquals(1, cache.size());
}
@Test
public void timedCachetest() {
String key = "key";
Thing thing = new Thing(key);
Assert.assertEquals(0, cache.size());
cache.put(key, thing);
Assert.assertEquals(1, cache.size());
try {
thing = cache.getIfPresent(key);
long millis = 100 * sec;
Thread.sleep(millis);
// cache.invalidateAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Assert.assertNotNull(thing);
Assert.assertEquals(key, thing.getName());
Assert.assertEquals(0, cache.size());
}
class Thing {
public Thing(String key) {
this.name = key;
this.value = key.hashCode();
}
public String getName() {
return name;
}
public Integer getValue() {
return value;
}
private String name;
private Integer value;
}
}
答案 0 :(得分:9)
在CacheBuilder
Javadoc:
如果请求expireAfterWrite或expireAfterAccess,则可能会在每次缓存修改,偶尔的缓存访问或对Cache.cleanUp()的调用时逐出条目。过期的条目可以在Cache.size()中计算,但对于读取或写入操作永远不可见。
CacheBuilder
缓存可以在特别请求时进行维护,也可以在缓存突变的一部分进行维护,或偶尔进行读取。它没有例如启动一个线程来做缓存维护,因为a)线程相对较重,b)某些环境限制线程的创建。