我正在尝试使用谷歌的番石榴缓存,我只是用 expireAfterWrite 测试它,间隔为 1 分钟。在我正在处理的应用程序中,有数百个用户。所以我的理解是,当第一个人访问缓存时,我们从数据库中填充它,然后一分钟计时器应该开始倒计时。现在缓存已满。我们总是会在那一分钟内从缓存中获取它。一分钟后,它将过期,我们再次从数据库中获取它。
但是,似乎每次我在一分钟内访问缓存时,计时器都会重置。这是为什么?如果我在一分钟内没有访问缓存,缓存就会过期并且工作正常。
代码:
Cache<Long, List<someObj>> cacheMap = CacheBuilder.newBuilder().maximumSize(maxSize).expireAfterWrite(maxTime, TimeUnit.MINUTES).removalListener(new RemovalListener<Long, List<someObj>>() {
public void onRemoval(RemovalNotification<Long, List<someObj>> notification) {
if (notification.getCause() == RemovalCause.EXPIRED) {
logger.info("Value " + notification.getValue() + " has been expired");
} else {
logger.info("Just removed for some reason");
}
}
}).build();
...
//Convert to ConcurrentHashMap
cacheMap = someCache.asMap();
...
public List<someObj> getAllData(final Long orgId, final User user) {
// Get requests from cache
List<Request> cacheList = overdueSlaMap.get(orgId);
// Fill cached requests if null
cacheList = fillCacheIfNecessary(orgId, cacheList, overdueSlaMap);
return cacheList;
}
//Strategy for reading and writing to cache
//This method is fine. On first load, cache is empty so we fill it from database. Wait one minute, value expires and cache is empty again so we get from cache.
//However, everytime I refresh the page the one minute timer starts again. Surely, the one minute timer within the Guava Cache should not refresh regardless of how many times I access the cache within that one minute period.
private List<someObj> fillCacheIfNecessary(List<someObj> cacheList, ConcurrentMap<Long, List<someObj>> cacheMap) {
// If the cache is empty then we will try to fill it from the database.
if (cacheList == null) {
logger.info("populating cache");
List<someObj> objList = new ArrayList<someObj>();
// if bla bla
if (such and such) {
objList = service.getFromDatabase(someArg);
} else {
objList = service.getFromDatabase(anotherarg);
}
// Concurrently lock the new cacheList retrieved from the database.
List<someObj> newValue = Collections.unmodifiableList(objList);
// Only insert if new value does not exist in cache map
List<someObj> oldValue = cacheMap.putIfAbsent(orgId, newValue);
// If old value already exists then we use the old value otherwise we use the new value
cacheList = ((oldValue != null && !oldValue.isEmpty()) ? oldValue : newValue);
}
return cacheList;
}
编辑
我从控制器调用缓存:
public ModelAndView getNotifications(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
User user = getCurrentUser();
CacheManager cacheManager = new CacheManager();
List<someObj> objList = new ArrayList<Request>();
// Get from database
if (bla bla) {
objList = getFromDatabase(user);
}
// Get from cache
else {
Long orgId = user.getUserOrganisation().getId();
objList = cacheManager.getAllData(orgId, user);
}
return new ModelAndView(SOMEVIEW);
}
它将有用的数据传递给将其传递给调用数据库的方法的方法。但是,我现在正在尝试重构我的代码以使用 LoadingCache 但这需要我重写 load() 方法,该方法只使用一个参数,这是关键。我需要的不仅仅是键,我需要调用控制器中的 cacheManager,所以它调用了适当的方法。什么是加载方法?什么时候使用?何时调用以及多久调用一次?它会使我的其他方法无效吗?