缓存击穿后单机只用一个线程命中Db策略

水深无声 2021-06-12 20:36 287阅读 0赞
  1. private ConcurrentHashMap<Integer, FutureTask<ShopDto> shopTaskMap = new ConcurrentHashMap<Integer, FutureTask<ShopDto>();
  2. public ShopDto loadShop(int shopId) {
  3. ShopDto dto = getFromCache(shopId);
  4. if (dto == null) {
  5. FutureTask<ShopDto> future = shopTaskMap.get(shopId);
  6. if (future == null) {
  7. FutureTask<ShopDto> task = new FutureTask<ShopDto>(new ShopDBTask(shopId));
  8. future = shopTaskMap.putIfAbsent(shopId, task);
  9. if (future == null) {
  10. future = task;
  11. future.run(); //确保本机只有一个线程命中DB
  12. }
  13. }
  14. try {
  15. dto = future.get(200, TimeUnit.MILLISECONDS);
  16. } catch (Exception e) {
  17. return null;
  18. } finally {
  19. shopTaskMap.remove(shopId);
  20. } } //end if (dto == null)
  21. return dto;
  22. }
  23. class ShopDBTask implements Callable<ShopDto>{
  24. private int shopId;
  25. public ShopDBTask (int shopId){
  26. this.shopId = shopId;
  27. }
  28. @Override
  29. public ShopDto call() throws Exception {
  30. ShopDto dto = loadFromDB(shopId);
  31. if(dto == null){
  32. dto = new ShopDto ();
  33. }
  34. setCache(shopId, ShopDto);
  35. return dto;
  36. } }

发表评论

表情:
评论列表 (有 0 条评论,287人围观)

还没有评论,来说两句吧...

相关阅读

    相关 缓存击穿

    *目录** 什么是缓存击穿 如何避免缓存击穿 -------------------- **什么是缓存击穿** 缓存击穿指请求到缓存中查询不存在的数据(缓存...

    相关 Redis:缓存击穿

    缓存击穿 缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。 解决方案: 1

    相关 缓存击穿策略singleFlight

    简介 缓存击穿:缓存失效时,有大量并发请求过来。大量请求从缓存上拿不到数据,请求压力全部打到数据库上。 场景1:活动结束前。为了完成活动任务,请求活动配置数据请求一般

    相关 缓存击穿问题

           缓存穿透是指查询一个一定不存在的数据,由于缓存不命中,并且出于容错考虑, 如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,