Home > Mobile >  Multi Requests break same class instance during execution
Multi Requests break same class instance during execution

Time:03-12

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()

CodePudding user response:

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

  • Related