如何在用户闲置一定时间后清除HashMap中的对话记录
实现闲置用户对话记录自动清理方案
核心思路
- 跟踪每个用户的最后活跃时间,通过时间差判断是否闲置
- 用定时任务定期扫描并清理超时用户的对话记录
- 使用线程安全的集合类,避免并发操作问题
具体实现步骤
1. 新增活跃时间跟踪与线程安全集合
替换原有HashMap为线程安全的ConcurrentHashMap,同时新增记录用户最后活跃时间的Map:
private static OpenAiService service; // 改用ConcurrentHashMap保证多线程环境下的安全操作 private static Map<String, List<ChatMessage>> conversations = new ConcurrentHashMap<>(); // 记录每个用户最后活跃的时间戳(毫秒) private static Map<String, Long> userLastActive = new ConcurrentHashMap<>(); // 闲置超时阈值:2分钟=120000毫秒 private static final long IDLE_TIMEOUT = 120000L; // 定时清理任务执行间隔:30秒检查一次 private static final long CLEANUP_INTERVAL = 30000L;
2. 更新用户活跃时间
在用户每次发起对话请求时,更新其最后活跃时间:
public static String generateChatResponse(User user, String prompt) { String userId = user.getId(); // 更新当前用户的最后活跃时间 userLastActive.put(userId, System.currentTimeMillis()); List<ChatMessage> conversation; if (conversations.containsKey(userId)) { conversation = conversations.get(userId); } else { conversation = new ArrayList<>(); } // 原有的对话构建、OpenAI请求、回复处理逻辑保持不变... conversations.put(userId, conversation); return response; }
3. 启动定时清理任务
在初始化OpenAI服务时,启动定时任务定期清理闲置用户:
public static void initializeOpenAi() { service = new OpenAiService(Settings.OPENAI_ACCESS_KEY); // 启动单线程定时任务 ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate(() -> { long currentTime = System.currentTimeMillis(); // 筛选出超时的用户ID List<String> idleUserIds = userLastActive.entrySet().stream() .filter(entry -> currentTime - entry.getValue() > IDLE_TIMEOUT) .map(Map.Entry::getKey) .collect(Collectors.toList()); // 清理闲置用户的对话记录和活跃时间记录 for (String userId : idleUserIds) { conversations.remove(userId); userLastActive.remove(userId); System.out.println("已清理闲置用户[" + userId + "]的对话记录"); } }, 0, CLEANUP_INTERVAL, TimeUnit.MILLISECONDS); }
4. 可选优化
- 如果是Web应用,可在用户连接断开时(如WebSocket的
onClose事件)主动清理该用户的记录,减少等待时间 - 根据业务场景调整
IDLE_TIMEOUT和CLEANUP_INTERVAL的数值,平衡清理精度与性能开销
内容的提问来源于stack exchange,提问作者Dylan Wedman
相关产品推荐
相关产品推荐

