背景:需要记录小程序用户登陆的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 USER_SESSIONKEY_CACHE = new ConcurrentHashMap<>();// key 为sessionId
// value为用户的sessionkey和openid
private static ScheduledExecutorService swapExpiredPool = new ScheduledThreadPoolExecutor(1);// 2线程去
// 移除过期时间的map和queue数据
private static PriorityBlockingQueue 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 stub
while (true) {
UserSessionKey keyInfo = queue.peek();
if (keyInfo == null || keyInfo.getCreateTime()