背景:需要记录小程序用户登陆的sessionid并与其openid关联,定时清除
核心代码实现
总体思路:使用ConcurrentHashMap去存缓存的对象,PriorityBlockingQueue去优化弹出(定时移除,按失效时间排序),ScheduledExecutorService去定期执行移除,初始化时调用单例对象的initial()方法


import java.text.DecimalFormat;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class UserSessionKeyCache {private static Logger LOGGER = LoggerFactory.getLogger(UserSessionKeyCache.class);private static UserSessionKeyCache singleton;private final static Map<String, UserSessionKey> USER_SESSIONKEY_CACHE = new ConcurrentHashMap<>();// key 为sessionId// value为用户的sessionkey和openidprivate static ScheduledExecutorService swapExpiredPool = new ScheduledThreadPoolExecutor(1);// 2线程去// 移除过期时间的map和queue数据private static PriorityBlockingQueue<UserSessionKey> queue = new PriorityBlockingQueue<>();// 按生成时间排序的队列public static synchronized UserSessionKeyCache initial() {LOGGER.info("初始化任务");if (singleton == null) {singleton = new UserSessionKeyCache();synchronized (UserSessionKeyCache.class) {swapExpiredPool.scheduleWithFixedDelay(() -> {LOGGER.info("执行任务");long now = System.currentTimeMillis();// TODO Auto-generated method stubwhile (true) {UserSessionKey keyInfo = queue.peek();if (keyInfo == null || keyInfo.getCreateTime() + TIME_ONE_TEN_DAYS > now) {return;}USER_SESSIONKEY_CACHE.remove(keyInfo.getPrivateSessionId());UserSessionKey deleted = queue.poll();LOGGER.info("删除" + deleted.getPrivateSessionId());}}, 1, 1, TimeUnit.DAYS);}}return singleton;}public static void put(String key, UserSessionKey keyInfo) {UserSessionKey oldKeyInfo = USER_SESSIONKEY_CACHE.put(key, keyInfo);if (oldKeyInfo != null) {queue.remove(oldKeyInfo);}queue.add(keyInfo);}public static UserSessionKey get(String key) {UserSessionKey keyInfo = USER_SESSIONKEY_CACHE.get(key);if (keyInfo != null && (keyInfo.getCreateTime() + TIME_ONE_WEEK >= System.currentTimeMillis())) {return keyInfo;}return null;}public static void removeCache(String key) {USER_SESSIONKEY_CACHE.remove(key);}}

缓存的对象

public class UserSessionKey implements Comparable<UserSessionKey> {private Long id;private String privateSessionId;private String sessionKey;private String openId;private Long createTime;。。。。省略getter setter@Overridepublic int compareTo(UserSessionKey o) {// TODO Auto-generated method stublong r = this.createTime - o.createTime;if (r > 0) {return 1;}if (r < 0) {return -1;}return 0;}

登陆时去存用户信息

public String cacheSession(String openId, HttpServletRequest request) {String currentSessionKey = uskDAO.queryUserSessionKeyByOpenId(openId);// HttpSession session=request.getSession();String privateSessionId = createSessionId(openId, currentSessionKey);/** Map<String,String> sessionkeyMap=new HashMap<>();//存sessionkey和openid* sessionkeyMap.put("sessionKey", currentSessionKey);* sessionkeyMap.put("openId", openId);*/UserSessionKey keyInfo = new UserSessionKey();keyInfo.setOpenId(openId);keyInfo.setCreateTime(System.currentTimeMillis());keyInfo.setPrivateSessionId(privateSessionId);UserSessionKeyCache.put(privateSessionId, keyInfo);System.out.println(privateSessionId);// session.setAttribute(sessionId, sessionkeyMap);//session存 sessionid为key// sessionkey openid为valuereturn privateSessionId;}

登陆拦截器去取用户openid

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.json.JSONObject;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import org.springframework.util.StringUtils;import com.alibaba.druid.support.json.JSONUtils;@Component
public class SessionInterceptor implements HandlerInterceptor {@AutowiredIUsersService uService;@AutowiredUserHostHolder userHostHolder;private final static Logger logger = LoggerFactory.getLogger(SessionInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)throws Exception {String privateSessionId = httpServletRequest.getHeader("sessionId");if (StringUtils.isEmpty(privateSessionId)) {return true;}UserSessionKey sessionkeyMap = UserSessionKeyCache.get(privateSessionId);if (sessionkeyMap != null) {String openId = sessionkeyMap.getOpenId();if (!StringUtils.isEmpty(openId)) {Users currentUser = uService.queryUserIdByOpenId(openId);if (currentUser != null && currentUser.getUserStatus().equals(USER_STATUS_ACTIVATED) ) {userHostHolder.setUser(currentUser);Map<String,String[]> m=httpServletRequest.getParameterMap();JSONObject j=new JSONObject(m);String headers=RequestHeaderUtils.getAllHeaders(httpServletRequest);logger.debug("START: 用户: {} ,请求链接: {}, 请求方式:{}, 请求参数:{}, 请求头:{}",currentUser.getUserId(),httpServletRequest.getRequestURI(),httpServletRequest.getMethod(),j.toString(),headers);return true;} else {responseErrorMsg(httpServletResponse);Map<String,String[]> m=httpServletRequest.getParameterMap();JSONObject j=new JSONObject(m);String headers=RequestHeaderUtils.getAllHeaders(httpServletRequest);logger.debug("START:!!!用户被禁用/信息异常---用户: {} ,请求链接: {}, 请求方式:{} 请求参数:{}, 请求头:{}",currentUser.getUserId(),httpServletRequest.getRequestURI(),httpServletRequest.getMethod(),j.toString(),headers);return false;}}} else {responseReloginMsg(httpServletResponse);return false;}return false;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,Object o, Exception e) throws Exception {try {userHostHolder.clear();} finally {userHostHolder.clear();}}private void responseErrorMsg(HttpServletResponse httpServletResponse) {httpServletResponse.reset();// 设置编码格式httpServletResponse.setCharacterEncoding("UTF-8");httpServletResponse.setContentType("application/json;charset=UTF-8");PrintWriter pw = null;try {Map<String, Object> resultMap = new HashMap<>();pw = httpServletResponse.getWriter();resultMap.put("retDesc", "用户被禁用");resultMap.put("retCode", RESPONSE_CODE1001);pw.write(JSONUtils.toJSONString(resultMap));pw.flush();pw.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {pw.close();}}private void responseReloginMsg(HttpServletResponse httpServletResponse) {httpServletResponse.reset();// 设置编码格式httpServletResponse.setCharacterEncoding("UTF-8");httpServletResponse.setContentType("application/json;charset=UTF-8");PrintWriter pw = null;try {Map<String, Object> resultMap = new HashMap<>();pw = httpServletResponse.getWriter();resultMap.put("retDesc", "登陆过期");resultMap.put("retCode", RESPONSE_CODE1002);pw.write(JSONUtils.toJSONString(resultMap));pw.flush();pw.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {pw.close();}}
}

如有错误请指正!
相互学习

JAVA实现HASHMAP缓存 并定时清理相关推荐

  1. JAVA延迟队列(实现数据的缓存和定时清理)

    在延迟队列中所保存的每一个元素内容.每当时间一到,(compareTo进行比较,getDelay()获取延迟时间),都会自动进行队里数据的弹出操作; 使用延迟队列(模拟讨论会依次离开的场景) publ ...

  2. php 定时缓存,php定时清理缓存文件的简单示例

    这篇文章主要为大家详细介绍了php定时清理缓存文件的简单示例,具有一定的参考价值,可以用来参考一下. 感兴趣的小伙伴,下面一起跟随512笔记的小玲来看看吧!那么有没有方法自动清理临时文件夹呢? 以下代 ...

  3. Linux 清理缓存,定时清理缓存脚本

    查看内存使用率 free -m | sed -n '2p' | awk '{print "used mem is "$3"M,total mem is "$2& ...

  4. java map 缓存数据_java使用hashMap缓存保存数据的方法

    本文实例讲述了java使用hashMap缓存保存数据的方法.分享给大家供大家参考,具体如下: private static final HashMap sCache = new HashMap(); ...

  5. java清空redis缓存数据库_java相关:Spring Cache手动清理Redis缓存

    java相关:Spring Cache手动清理Redis缓存 发布于 2020-4-24| 复制链接 摘记: 这篇文章主要介绍了Spring Cache手动清理Redis缓存,文中通过示例代码介绍的非 ...

  6. linux定时结束java进程_使用zt-exec库定时清理linux休眠进程

    在几个月前上线的一个采集项目,构架是基于java + selenium + chromedriver + chrome实现的采集.至于为哈不直接用jsoup或httpclient实现采集功能,是因为很 ...

  7. java hashMap缓存简单实现

    直接上代码,干货: import java.util.HashMap; import java.util.Map;/*** map缓存* @author ming** @param <K> ...

  8. Ubuntu定时清理缓存

    Ubuntu定时清理缓存 第一步:进入root用户,安装cron apt-get update apt-get install cron 第二步:进入/home目录,新建文件clear_buff_ca ...

  9. buff/cache内存缓存过大,设置定时清理

    buff/cache内存缓存过大,设置定时清理 buff/cache居然占用内存达到10个G的内存 1.编写脚本 vim cleanCache.sh sudo sh -c "echo 1 & ...

最新文章

  1. R语言构建文本分类模型:文本数据预处理、构建词袋模型(bag of words)、构建xgboost文本分类模型、基于自定义函数构建xgboost文本分类模型
  2. rsync 模块同步失败
  3. 解决PLSQL Developer 9连接oracle10g出现乱码
  4. 关于渗透的一些思路持续更新(自我理解)
  5. “约见”面试官系列之常见面试题第四十一篇之VUE生命周期(建议收藏)
  6. Java api在线
  7. SQL 2005 的存储过程和触发器调试大法
  8. CentOS 6 编译安装subversion-1.8.10+Apache2.4
  9. cctype 头文件定义 函数列表
  10. SpringCloud工作笔记085---SpringBoot项目中防止跨站脚本攻击功能添加
  11. 玩转SSRS第五篇---客户端报表
  12. 字节跳动 测试开发面经
  13. 极限编程价值观及最佳实践
  14. 苹果鼠标滚轮驱动_黑苹果仿冒秒控鼠标
  15. 超好用的卸载工具——geek
  16. 什么是 0day 漏洞,1day 漏洞和 nday 漏洞?
  17. linux挂nas盘步骤,家庭NAS之Ubuntu挂载硬盘
  18. 2、Lctech Pi(F1C200S)开发环境搭建(CherryPi,Mangopi,F1C100S)
  19. 【自学Python】Python IDLE使用
  20. 行业垂直型SaaS进击蓝海 中国版Salesforce潜藏何处

热门文章

  1. confluent【kafka企业版】安装配置————附带详细信息
  2. 非结构化商业文本信息中隐私信息识别Baseline
  3. 2018诺贝尔物理学奖揭晓!美法加三位科学家因激光研究获奖
  4. 论文阅读 之 Person Search by Multi-Scale Matching
  5. 阿里国际、eBay如何提高店铺销量—测评(补单)
  6. 直接插入排序(有图,有实例)
  7. CollectGarbage函数--JS清理垃圾,内存释放
  8. 【数据采集】scrapy 爬取当当 招商网 selenium 获取东方财经网数据
  9. mac 卸载 eclipse_终于换Mac啦!折腾了几天整理了一波Mac 新手必备的工具套餐!
  10. FAST-LIO论文解读与详细公式推导