多个请求在执行期间破坏同一个类实例

发布于 2025-01-13 10:23:51 字数 1091 浏览 2 评论 0原文

我有一个类用作缓存,它使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海夕 2025-01-20 10:23:51

我通过遵循 Google Guava Cache 如何使用并发哈希图和重入锁作为段来解决这个问题

I solved it by following how Google Guava Cache works with Concurrent Hashmap and Reentrance lock as Segment

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文