如果更多的1个线程访问Spring @Cacheable会阻塞吗?

时间:2014-11-12 17:34:45

标签: java spring caching spring-cache

如果标记为@Cacheable的方法需要10分钟才能完成,并且两个线程t1,t2将访问该方法。

t1在时间0访问(缓存方法现在第一次运行) t2在时间t1 + 5mins

进行访问

这是否意味着t2将不会访问数据大约5分钟,因为t1已经开始@Cacheable操作并且它将在5分钟内完成(因为它已运行5分钟)或将是新的t2调用@Cacheable的调用?

4 个答案:

答案 0 :(得分:3)

如果第一次执行的结果没有被缓存,则第二次调用将继续。

你应该明白@Cacheable以高速缓存的内容为中心(而不是具体的线程的执行上下文[好吧,有点;缓存仍然需要线程安全])。在执行方法时,首先检查缓存以查看密钥是否存在:如果t1需要一段时间才能完成,那么其结果将不会被缓存,因此并发执行将继续执行,而不考虑t1的执行

答案 1 :(得分:1)

正如巨像所解释的那样,在方法调用之前检查缓存。因此,如果项目不在缓存中(如t1 + 5分钟那样),则对线程t2也会发生方法调用。

没有"阻止"在@Cacheable注释上。 t2将调用该方法,就好像存在缓存未命中一样,因此t2也需要10分钟才能完成相同的方法。

答案 2 :(得分:1)

@Cacheable没有阻止。

但是您可以在缓存实现中使用阻塞缓存策略。发现第一个查询miss有责任重建缓存。其他查询等到重建缓存。

  • 对于本地缓存实施,请使用ReadWriteLock。请参阅net.sf.ehcache.constructs.blocking.BlockingCache
  • 对于远程缓存实施,请使用ghetto central lock。

答案 3 :(得分:0)

Spring 4.3起,您可以通过添加sync = true标志来获得所需的阻止行为:

@Cacheable(value="cacheName", key="{#keyField1, #keyField2}", sync = true)