多请求在执行期间中断相同的 class 实例
Multi Requests break same class instance during execution
我有一个 class 作为缓存使用 Map(HashMap 或 ConcurrentHashMap),我想在执行每个新的 (http) 请求之前清除我的 Map,例如
@Component
public Class MyCache {
Map cache = new ConcurrentHashMap();
get(key) {
cache.computeIfAbsent(key, fetchFromDB())
}
clearCache() {
cache.clear()
}
}
@Controller
public Class MyController {
@Autowired
MyCache myCache
@Get
Response getInfo(ids) {
// give me a fresh cache at beginning of every new request
myCache.clearCache()
// load and fetch from myCache of current request
ids.foreach(id -> {
myCache.get(id)
})
}
}
以上代码思路是
- 当有新请求进入时初始重置缓存
- 然后对于输入的所有id(可能是数百个),从缓存中获取
- 如果相同的id已经存储在缓存中,我们不需要重新调用fetchFromDB。
一切都在本地使用单线程工作,但是当调用 2 个或更多线程时,有可能在线程 1 执行期间,线程 2 启动并调用 myCache.clearCache()
,不知何故我的线程 1 突然发现没有存储在 myCache 中不再用于所有已处理的项目。
- 原因是因为我的映射在 class 中作为单例(例如 MyCache、Controller),即使每个请求处理它自己的线程,它们也会对同一个实例采取行动
- 如果我仍想为每个传入的请求获得干净的缓存,那么解决此问题的最佳方法是什么?无论如何,我可以检测到在当前线程 clearCache()
之前是否还有其他线程仍在执行
我按照 Google Guava Cache 与 Concurrent Hashmap 和 Reentrance lock as Segment 的工作方式解决了这个问题
我有一个 class 作为缓存使用 Map(HashMap 或 ConcurrentHashMap),我想在执行每个新的 (http) 请求之前清除我的 Map,例如
@Component
public Class MyCache {
Map cache = new ConcurrentHashMap();
get(key) {
cache.computeIfAbsent(key, fetchFromDB())
}
clearCache() {
cache.clear()
}
}
@Controller
public Class MyController {
@Autowired
MyCache myCache
@Get
Response getInfo(ids) {
// give me a fresh cache at beginning of every new request
myCache.clearCache()
// load and fetch from myCache of current request
ids.foreach(id -> {
myCache.get(id)
})
}
}
以上代码思路是
- 当有新请求进入时初始重置缓存
- 然后对于输入的所有id(可能是数百个),从缓存中获取
- 如果相同的id已经存储在缓存中,我们不需要重新调用fetchFromDB。
一切都在本地使用单线程工作,但是当调用 2 个或更多线程时,有可能在线程 1 执行期间,线程 2 启动并调用 myCache.clearCache()
,不知何故我的线程 1 突然发现没有存储在 myCache 中不再用于所有已处理的项目。
- 原因是因为我的映射在 class 中作为单例(例如 MyCache、Controller),即使每个请求处理它自己的线程,它们也会对同一个实例采取行动
- 如果我仍想为每个传入的请求获得干净的缓存,那么解决此问题的最佳方法是什么?无论如何,我可以检测到在当前线程 clearCache() 之前是否还有其他线程仍在执行
我按照 Google Guava Cache 与 Concurrent Hashmap 和 Reentrance lock as Segment 的工作方式解决了这个问题