消息~组件(群聊类型)ConcurrentHashMap发送

为什么选择ConcurrentHashMap?
在开发聊天应用时,我们需要存储和管理大量的聊天消息数据,这些数据会被多个线程频繁访问和修改。比如,当多个用户同时发送消息时,服务端需要同时处理这些消息的存储和查询。如果用普通的HashMap,可能会出现线程安全问题,比如数据被覆盖或者读取到错误的数据。
而ConcurrentHashMap是一个专门为多线程环境设计的数据结构,它的主要优点如下:

  1. 线程安全
    ConcurrentHashMap内部通过锁分段机制(或者在Java 8及以上版本中使用CAS操作和synchronized锁)来保证线程安全。这意味着多个线程可以同时读写它,而不会出现数据错乱的问题。
  2. 高性能
    相比普通的HashMap,ConcurrentHashMap在多线程环境下性能更高。它允许多个线程同时读取和更新数据,而不会像Collections.synchronizedMap那样锁住整个表。
  3. 支持高并发
    聊天应用通常需要处理大量的并发请求,比如同时接收和发送消息。ConcurrentHashMap能够很好地支持这种高并发场景,确保数据的读写操作不会成为性能瓶颈。
  4. 易于使用
    它的使用方式和普通的HashMap非常相似,几乎不需要额外的学习成本。只需要把HashMap替换为ConcurrentHashMap,就可以在多线程环境中安全地使用。
    举个例子
    假设我们有一个聊天应用,用户A和用户B同时向用户C发送消息。如果没有线程安全机制,可能会出现以下问题:
    ● 用户A的消息覆盖了用户B的消息。
    ● 用户C看到的消息顺序混乱。
    而ConcurrentHashMap可以很好地解决这些问题。它会确保每个消息都被正确存储,并且在多个线程同时操作时不会出现冲突。

总结
选择ConcurrentHashMap是因为它既安全又高效,特别适合聊天应用这种需要处理大量并发数据的场景。它能帮我们省去很多线程安全的麻烦,让代码更简洁,运行也更稳定。
希望这个解释清楚了为什么选择ConcurrentHashMap!
聊天应用中的私聊和群聊数据查询优化
在开发聊天应用时,如何查询和展示私聊和群聊的会话列表是一个关键问题。我们需要从服务端向客户端传递两种类型的数据:私聊消息和群聊消息。为了实现这一点,我们使用了ConcurrentHashMap来存储这些数据,确保线程安全和高效的并发访问。

聊天应用中的私聊和群聊数据查询优化

在开发聊天应用时,如何查询和展示私聊和群聊的会话列表是一个关键问题。我们需要从服务端向客户端传递两种类型的数据:私聊消息和群聊消息。为了实现这一点,我们使用了ConcurrentHashMap来存储这些数据,确保线程安全和高效的并发访问。

以下是服务端代码的结构:

ConcurrentHashMap<Long, List<ChatMessage>> messageMap = new ConcurrentHashMap<>();
ConcurrentHashMap<Long, List<GroupMessage>> groupMessageMap = new ConcurrentHashMap<>();

私聊会话查询

私聊会话的查询需要获取以下信息:

  1. 用户头像、用户名和会话是否置顶。
  2. 最后一条消息、最后活动时间和未读消息数量。

查询私聊用户信息

SELECT m.user_id, m.isPinned, u.username, u.image 
FROM friend m 
JOIN user u ON m.user_id = u.id 
WHERE m.friend_id = ?
  • friend:存储用户之间的关系,user_id表示好友的ID,friend_id表示当前用户的ID,isPinned表示是否置顶。
  • user:存储用户的基本信息,username是用户名,image是用户头像。

查询私聊消息信息

SELECT CASE WHEN sender_id = ? THEN receiver_id ELSE sender_id END as chat_id, MAX(time) as last_time,(SELECT content FROM messages m WHERE (m.sender_id = ? OR m.receiver_id = ?) AND (CASE WHEN m.sender_id = ? THEN m.receiver_id ELSE m.sender_id END) = chat_idAND m.room_id IS NULLORDER BY m.time DESC LIMIT 1) as last_message,SUM(CASE WHEN receiver_id = ? AND status = 0 THEN 1 ELSE 0 END) as unread_count
FROM messages 
WHERE (sender_id = ? OR receiver_id = ?) AND room_id IS NULL 
GROUP BY chat_id
ORDER BY last_time DESC;
  • messages:存储消息内容,sender_idreceiver_id分别表示发送者和接收者的ID,time表示消息发送时间,status表示消息的读取状态(0表示未读,1表示已读)。
  • 逻辑解释
    • CASE WHEN sender_id = ? THEN receiver_id ELSE sender_id END as chat_id:根据当前用户ID,确定对方的用户ID。
    • MAX(time):获取最后一条消息的时间。
    • 子查询获取最后一条消息的内容。
    • SUM(CASE WHEN receiver_id = ? AND status = 0 THEN 1 ELSE 0 END):统计未读消息的数量。

群聊会话查询

群聊会话的查询需要获取以下信息:

  1. 群组名称、群组头像、是否置顶。
  2. 最后一条消息、最后活动时间和未读消息数量。

查询群聊信息

SELECT g.id AS group_id,g.name AS group_name,g.image AS group_avatar,MAX(ug.timeship) AS last_active_time,(SELECT ug2.message FROM user_group ug2 WHERE ug2.group_id = g.id ORDER BY ug2.timeship DESC LIMIT 1) AS last_message,SUM(CASE WHEN ug.status = 1 AND ug.user_id != ? THEN 1 ELSE 0 END) AS unread_count,MAX(ug.isPinned) AS is_pinned
FROM groupsql g
JOIN user_group ug ON g.id = ug.group_id
WHERE ug.user_id = ? OR EXISTS (SELECT 1 FROM user_group WHERE group_id = g.id AND user_id = ?)
GROUP BY g.id, g.name, g.image
ORDER BY is_pinned DESC, last_active_time DESC;
  • groupsql:存储群组的基本信息,id是群组ID,name是群组名称,image是群组头像。
  • user_group:存储用户与群组的关系,group_id是群组ID,user_id是用户ID,timeship是用户加入群组的时间,message是群组消息,status表示消息的读取状态(1表示未读)。
  • 逻辑解释
    • MAX(ug.timeship):获取群组的最后活动时间。
    • 子查询获取最后一条消息的内容。
    • SUM(CASE WHEN ug.status = 1 AND ug.user_id != ? THEN 1 ELSE 0 END):统计未读消息的数量。
    • MAX(ug.isPinned):判断群组是否置顶。
    • ORDER BY is_pinned DESC, last_active_time DESC:按置顶优先级和最后活动时间排序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/905364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stapi知识框架

一、Stapi 基础认知 1. 框架定位 自动化API开发框架&#xff1a;专注于快速生成RESTful API 约定优于配置&#xff1a;通过标准化约定减少样板代码 企业级应用支持&#xff1a;适合构建中大型API服务 代码生成导向&#xff1a;显著提升开发效率 2. 核心特性 自动CRUD端点…

基于深度学习的水果识别系统设计

一、选择YOLOv5s模型 YOLOv5&#xff1a;YOLOv5 是一个轻量级的目标检测模型&#xff0c;它在 YOLOv4 的基础上进行了进一步优化&#xff0c;使其在保持较高检测精度的同时&#xff0c;具有更快的推理速度。YOLOv5 的网络结构更加灵活&#xff0c;可以根据不同的需求选择不同大…

Spring Security与SaToken的对比

Spring Security与SaToken的详细对照与优缺点分析 1. 核心功能与设计理念 对比维度Spring SecuritySaToken核心定位企业级安全框架&#xff0c;深度集成Spring生态&#xff0c;提供全面的安全解决方案&#xff08;认证、授权、攻击防护等&#xff09;轻量级权限认证框架&#…

【docker】--镜像管理

文章目录 拉取镜像启动镜像为容器连接容器法一法二 保存镜像加载镜像镜像打标签移除镜像 拉取镜像 docker pull mysql:8.0.42启动镜像为容器 docker run -dp 8080:8080 --name container_mysql8.0.42 -e MYSQL_ROOT_PASSWORD123123123 mysql:8.0.42 连接容器 法一 docker e…

力扣HOT100之二叉树:543. 二叉树的直径

这道题本来想到可以用递归做&#xff0c;但是还是没想明白&#xff0c;最后还是去看灵神题解了&#xff0c;感觉这道题最大的收获就是巩固了我对lambda表达式的掌握。 按照灵神的思路&#xff0c;直径可以理解为从一个叶子出发向上&#xff0c;在某个节点处拐弯&#xff0c;然后…

web 自动化之 yaml 数据/日志/截图

文章目录 一、yaml 数据获取二、日志获取三、截图 一、yaml 数据获取 需要安装 PyYAML 库 import yaml import os from TestPOM.common import dir_config as Dirdef read_yaml(key,file_name"test_datas.yaml"):file_path os.path.join(Dir.testcases_dir, file_…

rtty操作记录说明

rtty操作记录说明 前言 整理资料发现了几年前做的操作记录&#xff0c;分享出来&#xff0c;希望对大家有用。 rtty-master&#xff1a;rtty客户端程序&#xff0c;其中buffer\log\ssl为源码的子目录&#xff0c;从git上下载https://github.com/zhaojh329&#xff0c; rtty…

mybatis中${}和#{}的区别

先测试&#xff0c;再说结论 userService.selectStudentByClssIds(10000, "wzh or 11");List<StudentEntity> selectStudentByClssIds(Param("stuId") int stuId, Param("field") String field);<select id"selectStudentByClssI…

【运维】MacOS蓝牙故障排查与修复指南

在日常使用macOS系统过程中&#xff0c;蓝牙连接问题时有发生。无论是无法连接设备、连接不稳定还是蓝牙功能完全失效&#xff0c;这些问题都会严重影响我们的工作效率。本文将分享一些实用的排查方法和修复技巧&#xff0c;帮助你解决macOS系统上的蓝牙故障。 问题症状 常见…

数据结构(一) 绪论

一. 时间复杂度: (1)定义: 时间复杂度是衡量算法执行时间随输入规模(通常用n表示)增长的变化趋势的指标,时间复杂度用O符号表示 用于描述算法在最坏情况下或平均情况下的时间需求 时间复杂度关注的是操作次数的增长率&#xff0c;而非具体执行时间 常见的时间复杂度由小到大依次…

网络协议与系统架构分析实战:工具与方法全解

网络协议与系统架构分析实战&#xff1a;工具与方法全解 在互联网系统的开发、运维与安全分析中&#xff0c;协议解析与抓包分析是不可或缺的核心技能。本文将系统梳理主流协议解析工具、协议自动识别方案&#xff0c;并结合实际抓包案例&#xff0c;讲解如何还原和推测底层系…

发那科机器人4(编程实例)

发那科机器人4(编程实例) 一、编程实例1、直线运动实例2、圆弧运动实例3、曲线运动实例4、物料搬运实例5、异步输送带检测一、编程实例 1、直线运动实例 本节内容:直线运动实例 本次实例,采用的是基础模块,以基础模块当中的四边形为例,演示一下机器人的直线运动。 编程…

agent初识

AI Agent 时代已来&#xff1a;不止于聊天的智能体&#xff0c;将如何重塑我们的世界&#xff1f; AI Agent 时代已来&#xff1a;不止于聊天的智能体&#xff0c;将如何重塑我们的世界&#xff1f; 你是否曾惊叹于 ChatGPT 的对答如流&#xff1f;或者 Midjourney 的妙笔生花…

.Net HttpClient 使用Json数据

HttpClient 使用Json数据 现代Web项目中&#xff0c;Json是最常用的数据格式。不论是前后端的交互中&#xff0c;还是纯前端项目中&#xff0c;都是如此。因此&#xff0c;.Net HttpClient 能不能更加方便、快捷的处理Json格式数据&#xff0c;也就至关重要了&#xff01; 文末…

UDP--DDR--SFP,FPGA实现之指令监测模块实现

指令监测模块实现介绍 如下图所示&#xff0c;为指令监测模块的运行框图 将指令设置为8bytes数据&#xff0c;故需要一个64位寄存器进行缓存&#xff0c;在进行数据缓存时&#xff0c;数据不可以输出至下一级模块&#xff0c;故对数据和有效指示信号也应该进行相应延迟&#…

JavaScript双问号操作符(??)详解,解决使用 || 时因类型转换带来的问题

目录 JavaScript双问号操作符&#xff08;??&#xff09;详解&#xff0c;解决使用||时因类型转换带来的问题 一、双问号操作符??的基础用法 1、传统方式的痛点 2、双问号操作符??的精确判断 3、双问号操作符??与逻辑或操作符||的对比 二、复杂场景下的空值处理 …

智能体的典型应用:自动驾驶、智能客服、智能制造、游戏AI与数字人技术

本文为《React Agent&#xff1a;从零开始构建 AI 智能体》专栏系列文章。 专栏地址&#xff1a;https://blog.csdn.net/suiyingy/category_12933485.html。项目地址&#xff1a;https://gitee.com/fgai/react-agent&#xff08;含完整代码示​例与实战源&#xff09;。完整介绍…

Ubuntu 22.04(WSL2)使用Docker安装Redis

Ubuntu 22.04&#xff08;WSL2&#xff09;使用Docker安装Redis 本教程将指导您在运行于WSL2的Ubuntu 22.04上通过Docker安装Redis 7.4.3。您将获得一个配置了自定义设置、持久化存储和安全选项的Redis实例。 前提条件 WSL2上已安装Ubuntu 22.04。WSL2上已安装并运行Docker&…

浅谈 Redis 数据类型

浅谈 Redis 数据类型 &#xff08;一&#xff09;String 类型 Redis 的 String 类型 是二进制安全的&#xff0c;可以用来存储 文本字符串、int 类型数据和 bitmap 位图 等数据。 1. 字符串操作 适用于存储 文本、JSON、序列化数据 等任意二进制安全的内容 命令作用示例SET设…

Day1 时间复杂度

一 概念 在 C 中&#xff0c;时间复杂度是衡量算法运行时间随输入规模增长的趋势的关键指标&#xff0c;用于评估算法的效率。它通过 大 O 表示法&#xff08;Big O Notation&#xff09; 描述&#xff0c;关注的是输入规模 n 趋近于无穷大时&#xff0c;算法时间增长的主导因…