0

0

模拟简单的社交关系系统_Map嵌套Set实现好友关注逻辑实战

P粉602998670

P粉602998670

发布时间:2026-02-17 09:33:32

|

170人浏览过

|

来源于php中文网

原创

不能直接用hashset存关注列表,因其非线程安全,并发增删易丢数据或抛concurrentmodificationexception;应使用collections.synchronizedset或concurrenthashmap.newkeyset()。

模拟简单的社交关系系统_map嵌套set实现好友关注逻辑实战

Map> 为什么不能直接用 HashSet 存关注列表

因为 HashSet 不保证线程安全,而社交关系的增删(比如“关注”“取关”)常并发发生。你用 new HashMap()new HashSet(),看似能跑通,但一旦两个请求同时对同一个用户的关注集合调 add()remove(),就可能丢数据或抛 ConcurrentModificationException

实操建议:

  • 关注集合统一用 Collections.synchronizedSet(new HashSet()) 包一层,或者更推荐——直接用 ConcurrentHashMap.newKeySet()(Java 8+),它底层是分段锁,性能更好
  • Map 层别偷懒用 HashMap,必须换成 ConcurrentHashMap,否则 putIfAbsent、computeIfAbsent 这类原子操作没法保障
  • 别在循环遍历 Set 时修改它,哪怕加了同步也不行;要改就先转成新集合再替换,例如:userFollows.replace(userId, Collections.unmodifiableSet(newFollowSet))

computeIfAbsent 是不是万能的“懒加载”写法

不是。它只保证“键不存在时创建并放入”,但不保证“创建出来的值本身线程安全”。比如写 map.computeIfAbsent(uid, k -> new HashSet()),多个线程同时触发,可能生成多个 HashSet 实例,只留一个进 map,其余被 GC——看起来没毛病,但后续对这个 Set 的操作还是非线程安全的。

实操建议:

  • 把集合初始化逻辑和线程安全绑定:用 computeIfAbsent(uid, k -> ConcurrentHashMap.newKeySet())
  • 如果 JDK 版本低于 8,老老实实用双重检查 + synchronized(map) 块,别图省事
  • 注意 computeIfAbsent 的 lambda 不能有副作用(比如发通知、写日志),它可能被多次执行(虽然最终只存一个)

“互相关注”判断为什么不能只查两次 contains

因为 a-follows-bb-follows-a 是两条独立路径,中间可能有时间差。比如 A 关注 B 后,B 还没点确认(如果是双向关注模型),或 B 刚取关 A,但 A 的缓存还没刷新——这时候单纯查 follows.get(a).contains(b) && follows.get(b).contains(a),结果不稳定,且容易误判。

实操建议:

  • 业务上需要“互关”状态,就单独建一张 mutual_follow 表或 Redis 的 SET,由关注/取关事件驱动更新,不要实时计算
  • 如果必须实时判断,至少加读锁或用 StampedLock 读模式包裹两次查询,避免中间态被修改
  • 测试时重点模拟“关注→取关→再关注”的毛刺场景,观察是否出现短暂的单向/双向状态错乱

内存暴涨是不是因为 String 用户 ID 没复用

是。如果用户 ID 来自 HTTP 参数或 JSON 解析,每次都是新 String 实例,Map 的 key 就无法复用,导致大量重复字符串对象堆积。10 万用户,每个 ID 平均 12 字节,光 key 就多占几 MB 内存,加上每个 ConcurrentHashMap 的桶数组和 KeySet 开销,很容易 OOM。

实操建议:

  • 所有外部进来的用户 ID,第一时间调 intern()(前提是 ID 稳定、总量可控);或用 String.valueOf(id).intern() 避免空指针
  • 更稳妥的做法:用 LongInteger 当用户主键,ID 映射走数据库或本地缓存,Map 的 key 改成数字型,省空间又快
  • jmap -histo 定期看堆里 java.lang.String 实例数,超过用户量 2 倍就要查来源

嵌套结构看着简单,但 Map 的并发策略、Set 的实例生命周期、字符串的内存驻留——这三个地方任何一个没抠准,线上跑一周就可能出问题。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

442

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

544

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

322

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

81

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

750

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

553

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

216

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1553

2023.10.24

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

283

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号