8

我有一个单例类(@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 注释没有考虑同步......这是一个错误吗?

4

2 回答 2

30

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

于 2016-09-12T03:24:54.127 回答
12

当您使用@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
}

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

于 2015-03-05T17:04:33.500 回答