我有一个单例类(@Service annotated)。该类有一个需要200 / 300ms才能执行的方法。
此方法使用@Cacheable和synchronized进行注释。
@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 / 300ms,直到结果未缓存,它会一次又一次地执行该方法,直到缓存为止。 似乎@Cacheable注释不会将 synchronized 考虑在内...... 这是一个错误吗?
答案 0 :(得分:17)
好消息,spring framework 4.3通过在@Cacheable中添加sync = true提供了一种支持您需求的方法。
答案 1 :(得分:10)
使用@Cacheable注释时,实现缓存搜索的代码不在您的方法中。因此,synchronized修饰符不会影响它。
如果希望所有线程都使用缓存结果,则应创建一个synchronized方法,将调用包装到可缓存的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
}
这些方法属于不同的类很重要。否则,这些方面都不起作用。