多个请求在执行期间破坏同一个类实例
我有一个类用作缓存,它使用 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个或更多线程调用时,有可能在thread1执行期间,thread2启动并且它会调用myCache.clearCache()
,不知何故我的thread1突然发现myCache 中不再存储所有已处理项目的内容。
- 原因是因为我的地图在类中是单例(例如 MyCache、Controller),而即使每个请求处理自己的线程,它们也会对同一个实例采取操作
- 如果我仍然想解决这个问题,最好的方法是什么为每个进来的请求获取一个干净的缓存?无论如何,我可以检测在我当前线程clearCache()之前是否还有其他线程仍在执行
I have a class played as cache which uses a Map (either HashMap or ConcurrentHashMap), I'd like to clear my Map before executing each new (http) request, e.g
@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)
})
}
}
Above code idea is to
- initially reset cache when a new request comes in
- then for all id of input(could be hundreds), fetch from cache
- if same id already stored in cache, we don't need to re-call fetchFromDB.
Everything works locally with single thread, but when calling with 2 or more threads, there are chances that during the execution of thread1, thread2 started and it would call myCache.clearCache()
, somehow my thread1 suddenly found nothing stored in myCache anymore for all its processed items.
- The reason is because my map was in class as singleton (e.g MyCache, Controller), while even each request deals with its own thread, they will take action on same instance
- What's the best way that I would fix this issue if I still wants to get a clean cache for each request comes in? Anyway I can detect if there might be other threads still executing before my current thread clearCache()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我通过遵循 Google Guava Cache 如何使用并发哈希图和重入锁作为段来解决这个问题
I solved it by following how Google Guava Cache works with Concurrent Hashmap and Reentrance lock as Segment