我不太清楚该如何处理this...so,我可能需要几次尝试才能正确回答这个问题。我有一个用于缓存方法结果的注释。我的代码现在是私有的分叉,但我正在处理的部分从这里开始:https://code.google.com/p/cache4guice/source/browse/trunk/src/org/cache4guice/aop/CacheInterceptor.java#46
我注释了一个我想要缓存的方法,它运行一个非常慢的查询,有时运行几分钟。问题是,我的异步web应用程序不断收到新用户,并要求相同的数据。但是,getSlowData()方法尚未完成。
所以就像这样:
@Cached
public getSlowData() {
...
}在拦截器中,我们检查缓存并发现它没有缓存,这会将我们传递给:
return getResultAndCache(methodInvocation, cacheKey);我从来没有适应过并发的整个概念。我认为我需要标记的是,对于给定的getResultAndCache()的getSlowData()方法已经被启动,随后的请求应该等待结果。
谢谢你的想法或建议!
发布于 2013-11-12 16:50:04
大多数缓存实现将调用同步到“get”和“set”,但这只是等式的一半。您真正需要做的是确保只有一个线程进入‘检查如果加载,如果没有加载’部分。对于大多数情况,序列化线程访问的成本可能不值得,如果
1) no risk
2) little cost通过并行线程多次加载数据(如果需要更多的说明,请在这里注释)。由于这个注释是普遍使用的,所以我建议创建第二个注释,类似于'@ThreadSafeCached‘,invoke方法将如下所示
Object cacheElement = cache.get(cacheKey);
if (cacheElement != null) {
LOG.debug("Returning element in cache: {}", cacheElement);
} else {
synchronized(<something>) {
// double-check locking, works in Java SE 5 and newer
if ((cacheElement = cache.get(cacheKey)) == null) {
// a second check to make sure a previous thread didn't load it
cacheElement = getResultAndCache(methodInvocation, cacheKey);
} else {
LOG.debug("Returning element in cache: {}", cacheElement);
}
}
}
return cacheElement;现在,我离开了关于你们同步的部分。最理想的方法是锁定正在缓存的项,因为您不会让任何线程不具体地加载这个缓存项等待。如果这是不可能的,另一种粗糙的方法可能是锁定注释类本身。这显然效率较低,但如果您无法控制缓存加载逻辑(似乎是这样),这是一个简单的出路!
https://stackoverflow.com/questions/19877383
复制相似问题