首页
学习
活动
专区
圈层
工具
发布

AOP +同步
EN

Stack Overflow用户
提问于 2013-11-09 15:02:43
回答 1查看 726关注 0票数 0

我不太清楚该如何处理this...so,我可能需要几次尝试才能正确回答这个问题。我有一个用于缓存方法结果的注释。我的代码现在是私有的分叉,但我正在处理的部分从这里开始:https://code.google.com/p/cache4guice/source/browse/trunk/src/org/cache4guice/aop/CacheInterceptor.java#46

我注释了一个我想要缓存的方法,它运行一个非常慢的查询,有时运行几分钟。问题是,我的异步web应用程序不断收到新用户,并要求相同的数据。但是,getSlowData()方法尚未完成。

所以就像这样:

代码语言:javascript
复制
@Cached
public getSlowData() {
...
}

在拦截器中,我们检查缓存并发现它没有缓存,这会将我们传递给:

代码语言:javascript
复制
return getResultAndCache(methodInvocation, cacheKey);

我从来没有适应过并发的整个概念。我认为我需要标记的是,对于给定的getResultAndCache()的getSlowData()方法已经被启动,随后的请求应该等待结果。

谢谢你的想法或建议!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-12 16:50:04

大多数缓存实现将调用同步到“get”和“set”,但这只是等式的一半。您真正需要做的是确保只有一个线程进入‘检查如果加载,如果没有加载’部分。对于大多数情况,序列化线程访问的成本可能不值得,如果

代码语言:javascript
复制
 1) no risk 
 2) little cost

通过并行线程多次加载数据(如果需要更多的说明,请在这里注释)。由于这个注释是普遍使用的,所以我建议创建第二个注释,类似于'@ThreadSafeCached‘,invoke方法将如下所示

代码语言:javascript
复制
    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;

现在,我离开了关于你们同步的部分。最理想的方法是锁定正在缓存的项,因为您不会让任何线程不具体地加载这个缓存项等待。如果这是不可能的,另一种粗糙的方法可能是锁定注释类本身。这显然效率较低,但如果您无法控制缓存加载逻辑(似乎是这样),这是一个简单的出路!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19877383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档