并发编程第一节
⚙️ 一、高并发核心概念
-
高并发定义
指系统在单位时间内能同时处理大量请求的能力,通常伴随瞬时流量爆发(如双十一秒杀、12306抢票)。关键指标包括:- QPS(每秒查询数):衡量服务端处理能力。
- 响应时间:请求发出到收到响应的耗时(如200ms为良好标准)。
- 吞吐量:单位时间成功处理的请求量。
-
典型高并发场景
- 电商促销:双十一瞬时下单压力(订单提交、库存扣减)。
- 金融交易:股票交易平台开盘时的集中交易请求。
- 社交热点:微博热搜导致海量用户同时刷新评论。
- 直播互动:百万级用户实时弹幕和礼物消息。
⚠️ 二、高并发下的数据不一致问题
当多线程同时读写共享数据时,若缺乏同步机制,会导致:
- 原子性破坏
- 问题:复合操作(如“读取-修改-写入”)被线程切换打断。
- 示例:两个线程同时读取库存为10,各扣减1后都写入9,实际应剩8。
- 可见性问题
- 原因:线程修改数据后未及时刷回主存,其他线程读取旧值(CPU缓存未同步)。
- 有序性问题
- 指令重排序:编译器/CPU优化可能改变代码执行顺序,导致意外结果。
案例:未加锁的HashMap并发put可能引发链表成环(JDK1.7)或数据覆盖。
🔧 三、关键术语解析
-
多线程扩容
- 定义:多个线程协作完成数据迁移(如ConcurrentHashMap扩容时)。
- 流程:
- 线程A触发扩容,通过
transferIndex
分配迁移区间(如负责桶16-31)。 - 线程B访问正在迁移的桶时,会协助迁移(通过
ForwardingNode
标识)。
- 线程A触发扩容,通过
- 优势:避免单线程迁移阻塞请求,提升扩容效率。
-
哈希冲突
- 定义:不同Key经哈希函数计算后得到相同桶地址(如Key1和Key2均映射到数组索引5)。
- 解决方案:
- 链表法:冲突键值对组成链表(JDK8前)。
- 红黑树:链表长度≥8时转为树,查询复杂度从O(n)降至O(log n)。
-
细粒度(Fine-Grained)
- 含义:将锁的粒度缩小到最小单位(如ConcurrentHashMap中锁单个桶而非整个表)。
- 目的:减少线程竞争,提高并发度。
🛡️ 四、ConcurrentHashMap的原子性实现
ConcurrentHashMap通过以下机制保证原子性操作:
-
CAS(Compare And Swap)
- 原理:若变量当前值等于预期值,则更新为新值;否则重试或放弃。
- 应用:初始化数组、更新桶头节点等无锁操作。
- 示例:
put
时若桶为空,直接用CAS写入新节点,失败则重试。
-
synchronized锁细化
- 锁对象<