- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 Google 的 Guava Cache,并且我只是以 1 分钟的间隔使用 expireAfterWrite 对其进行测试。在我正在开发的应用程序中,有数百个用户。所以我的理解是,当第一个人访问缓存时,我们从数据库中填充它,然后一分钟计时器应该开始倒计时。现在缓存已满。我们总是会在那一分钟的时间内从缓存中获取它。一分钟后,它就会过期,我们再次从数据库中获取它。
但是,似乎每次我在一分钟内访问缓存时,计时器都会重置。这是为什么?如果我在一分钟内没有访问缓存,缓存就会过期并正常工作。
代码:
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;
}
编辑
我从 Controller 调用缓存:
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() 方法,该方法仅使用一个关键参数。我需要的不仅仅是 key ,我还需要调用 Controller 中的cacheManager,因此它会调用适当的方法。加载方法是什么?什么时候使用?什么时候调用以及多久调用一次?它会使我的其他方法失效吗?
最佳答案
我相信您的问题是您正在使用从 asMap
返回的 Map
作为缓存。 asMap
被记录为返回存储在该缓存中的条目 View 作为线程安全映射
。这里没有任何内容表明您可以使用 Map
作为缓存。我建议更新您的代码以使用 Cache
API 并直接在缓存上调用 put
或 get(key, Callable)
。
您可能需要考虑使用 LoadingCache
,因为我发现 API 更简单。
编辑
所以首先,只有当缓存中不存在该键时才会调用 load 方法。缓存调用 load 方法来获取应为其键返回的值,然后缓存该值以供下次使用。使用 CacheLoader 或 Callable 的好处之一是检索数据的调用是线程安全的,因为每个键仅调用一次,即使多个键也只调用一次对同一 key 的调用同时发生。
如果您需要传递更多信息,请创建一个包装对象,如下所示:
public class MyKey{
final Long orgId; // true key value
final User user; // other values needed
// implement equals and hashCode to ONLY use orgId. This will ensure that
// the same cached value is returned for all requests with the same
// orgId which is the ACTUAL key.
}
您还可以使用常规Cache
执行相同的操作,并创建一个包含所需值的Callable
。
我建议 CacheLoader
使 fillCacheIfNecessary
无效。对 cache.get()
的简单调用将在内部确定该值是否必须检索或已存在于缓存中。它正在为您执行获取、检查是否为空、检索
工作。
关于java - ExpireAfterWrite 似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26909698/
谁能帮我解决这个问题?我有一个 Tomcat 和简单的 JSF 应用程序:https://github.com/gooamoko/jsfbilling/ .当我在 Tomcat 上运行应用程序时,它运
我有两个这样的域类,第一个是 Manager : package com.mnm class Manager { String name; static hasMany = [ pro
当我运行以下代码时,打印输出似乎不正确。 void thread_Calc(int *pos) { printf("recieved %d\n", *pos); sig = -1; man
这个问题在这里已经有了答案: How to access a local variable from a different function using pointers? (10 个答案) 关闭
我编写了一个程序,其中列表构建器方法返回 IEnumerable of string,其中包括大量字符串(100 万个项目),我将其存储在 List of string 中,然后它将所有项目附加到 中
我正在尝试编写一个 IRC 类型的聊天客户端,它具有可以连接到服务器的客户端。我试图让它在本地 atm 上工作(使用 FIFOS 而不是套接字)。 我遇到了以下我似乎无法解决的问题: 接受新的客户端连
我的一个 cronjobs 每天发送一封电子邮件 35 6 * * * cd $EZPUBLISHROOT && $PHP runcronjobs.php -q 2>&1 我停止使用 cron sud
我使用 WPF 打印路径来处理在我们的应用程序中创建的大型图表。整个图表由视觉效果组成。 所谓的“DesignerPaginator”对图表进行分页(非常简单)。 从这一点来说,我做了以下三件事: -
我尝试在更新之前跟踪系统应用程序并使用: public static boolean isSystemApplication(Context ctx, IContent content) {
我在这里附上了一个查询分析结果,https://explain.depesz.com/s/x9BN 这是查询 EXPLAIN ANALYZE SELECT branche
我正在做一个 CXF(spring) 项目 (HUB)。部署后,我可以看到肥皂和休息服务列表,我通过两个地址打开它。一种是使用本地主机,第二种是使用我电脑的 ip。所以我得到了这些输出。 使用本地主机
这是一个 AnyHashable 不支持枚举转换的简单案例。 enum testEnum: String { case Test } let myObject: AnyHashable = t
我的主要目标是比较存储在数据库和 XLSX 文件中的数据。 为此,我按以下方式创建了两个列表: private class ProductList { public string produc
我从 CMake 3.6 更新到任何最新版本 (3.12.0-rc2),现在我的一个程序无法编译。 奇怪的是,错误消息显示了标准库本身中的 undefined symbol 。这是错误消息: Unde
我希望将我的自定义对话框动画化为从特定点出现,但我无法为对话框设置动画。 该对话框是一个基本的 RelativeLayout,设置为 extends Dialog 类中的布局。 正如这里的一些答案所建
我已经在这个论坛上调查过很多类似的问题,但似乎没有一个能解决我的问题。 我会在底部列出我在这个论坛上看到的一些问题页面,但让我先谈谈我对这个问题的看法。 我正在使用 codeigniter v 2.x
我正在尝试在 RHEL 7 上启动一个 docker-compose 项目作为 systemd 服务。这是我的 systemd 脚本 (/etc/systemd/system/wp.service):
这个问题已经有答案了: "Notice: Undefined variable", "Notice: Undefined index", "Warning: Undefined array key",
我正在尝试在 RHEL 7 上启动一个 docker-compose 项目作为 systemd 服务。这是我的 systemd 脚本 (/etc/systemd/system/wp.service):
此问题出现在my last question here之后。我想将每个按钮聚焦和失去焦点背景设置为主菜单(ContentPane 即 JPanel)下方的背景颜色,因此按钮看起来像选项卡。它在不同的环
我是一名优秀的程序员,十分优秀!