【问题标题】:Spring cacheable not synchronizedSpring 可缓存不同步
【发布时间】:2015-05-07 03:28:04
【问题描述】:

我有一个单例类(@Service 注释)。这个类有一个需要 200/300ms 执行的方法。

这个方法被@Cacheable注解并且同步了。

@Cacheable(value="nextPlaying", key = "#startingFrom.getYear() + #startingFrom.getMonth() + #startingFrom.getDay() + #startingFrom.getHours() + #startingFrom.getMinutes() + #locale.getLanguage()")
public synchronized List<Match> getNextPlaying(Date startingFrom, Locale locale)

通过启动多个调用此方法的线程,我看到对于这 200/300 毫秒,直到结果未被缓存,它会一次又一次地执行该方法,直到被缓存。 似乎 @Cacheable 注释没有考虑到 synchronized ... 这是一个错误吗?

【问题讨论】:

标签: java spring spring-cache


【解决方案1】:

当您使用@Cacheable 注解时,实现缓存搜索的代码在您的方法之外。因此,同步修饰符不会影响它。

如果您希望所有线程都使用缓存的结果,您应该创建一个同步方法,将调用包装到可缓存的 getNextPlaying 方法。像这样的:

public synchronized List<Match> getNextPlayingSynchronized(Date startingFrom, Locale locale){
     return getNextPlaying(Date startingFrom, Locale locale);
}
...
@Cacheable(value="nextPlaying", key = "#startingFrom.getYear() + #startingFrom.getMonth() + #startingFrom.getDay() + #startingFrom.getHours() + #startingFrom.getMinutes() + #locale.getLanguage()")
public List<Match> getNextPlaying(Date startingFrom, Locale locale){
...//your old method without the synchronized modifier
}

这些方法位于不同的类中,这一点很重要。否则,这些方面不起作用。

【讨论】:

  • 不错的解决方案,但是它不会缓存任何东西,永远不会:S 我不明白为什么
  • @ianaz。将方法放在不同的类别中。否则,这些方面不起作用。
  • 这不起作用,因为spring创建了一个代理类,当您从同一类内部调用@Cachable时,它不会通过代理,因此不会缓存。 a) 把它放在不同的类 b) 使用 cglib c) 使用自我引用(导入你自己的类 \\@Autowired MyClass self; 然后调用 self.getNextPlaying)
【解决方案2】:

好消息,spring framework 4.3 提供了一种方法来支持您的需求,通过在 @Cacheable 中添加 sync=true。

【讨论】:

猜你喜欢
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-13
  • 2018-04-22
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
相关资源
最近更新 更多