问题描述
假设我有一个方法A,它是@Cacheable的,但是许多线程可以使用相同的参数同时访问它。
我想确保只有第一个线程创建缓存,以防止其他所有线程处理他们的请求。
我当然可以使用同步包装方法。但这将导致所有线程都将阻塞该方法。而且,同步不会包装@Cacheable AOP。
那么,有没有一种方法可以立即使用Spring来实现呢?
解决方法
请参见@Cacheable
注释sync
属性(Javadoc)和Reference Documentation。
此外,正如 @dnault 所提到的,它还缓存提供程序实现的相关性。并非所有的缓存提供程序都可能支持此选项,因此请检查您的缓存提供程序是否支持。
关于...
“ 我想确保只有第一个线程创建缓存,以防止所有其他线程处理他们的请求。”
缓存同步不是要与“缓存本身的创建”同步,而是要与缓存的条目(按键)同步。
缓存是Map
(即键/值存储/数据结构)。
例如,如果我有一个有助于缓存的应用程序服务方法,例如:
@Service
class UserService {
@Cacheable(cacheNames = "UsersByName",sync = true)
User findBy(String name) {
...
}
}
然后,如果给定...
Thread A: userService.findBy("janeDoe");
Thread B: userService.findBy("jonDoe");
Thread C: usesService.findBy("janeDoe");
仅线程C 将阻塞并等待线程A 计算的缓存结果。
线程B 将继续不间断地查找或计算“ jonDoe ”的User
。
还要注意,大多数缓存提供程序都希望在应用程序配置/启动时已经存在“ UsersByName ”缓存。