945 字
约 3 分钟
6
S05-J02 · 并发容器:CHM、阻塞队列、COW
2024-12-31
2026-11-07

适用读者:还在用 Collections.synchronizedMap 的人。
前置:S05-B03、S04-J02(HashMap 源码)。
覆盖旧文:A-1588(247) A-1597(109) A-824(85) A-1591(70) + 835(85) 836(70) = 666 点。
覆盖扩展:E-S05-009(CHM 的 CAS+synchronized、COW 边界)。
上一篇:S05-J01 · AQS 与 ReentrantLock 源码
下一篇:S05-J03 · CompletableFuture。


1. 一句话结论

并发容器的演进只有一条主线:把"一把大锁"换成"更细的锁 + 无锁结构"。ConcurrentHashMap 是这条线的教科书。

容器 并发策略
Hashtable 全表 synchronized(最慢)
Collections.synchronizedMap 全表锁(同上)
CHM(JDK 7) 分段锁(Segment,默认 16)
CHM(JDK 8+) CAS + 桶级 synchronized(锁单个桶头)
CopyOnWriteArrayList 写时复制(读写分离)

2. 为什么 JDK 8 废弃分段锁(E-S05-009)

维度 JDK 7 分段锁 JDK 8 桶级锁 + CAS
锁粒度 16 段(固定) 每个桶头(更细)
并发度 受段数限制(16) 随桶数增长(可到容量级)
空桶写入 需锁整段 CAS 直接放(无锁)
结构 Segment[] → HashEntry[] Node[] + 链表/红黑树(与 HashMap 同构)

一句话:分段锁的"段数"成了上限,而桶级锁把并发度提到"桶数"——同时复用 HashMap 的红黑树优化。

2.1 三个关键机制

机制 作用
读操作不加锁(volatile 保证可见) 高并发读几乎无开销
空桶插入用 CAS 无竞争时无锁
桶非空时 synchronized 桶头 只锁一个桶

3. COW:写时复制(A-1591)

List<String> list = new CopyOnWriteArrayList<>();
list.add("x");    // 复制整个数组 + 加新元素 + 替换引用
特性 说明
读 完全无锁(读旧数组快照)
写 复制整个数组(O(n))+ 加锁
内存 写时存在两份数组
迭代器 快照,不抛 CME

判据:"读远多于写、且数据量不大?" 是 → COW;否则用 ArrayList + 外部锁或 ConcurrentLinkedQueue。

典型场景:配置列表、监听器列表(读多写极少)。


4. 阻塞队列:线程池的"缓冲区"(A-1597)

队列 结构 有界 典型用途
ArrayBlockingQueue 数组 ✅ 必须指定 线程池首选(防 OOM)
LinkedBlockingQueue 链表 可选(默认无界) 注意默认无界的坑(B05)
SynchronousQueue 不存储 容量 0 直接交接(newCachedThreadPool)
PriorityBlockingQueue 堆 无界 优先级任务
DelayQueue 延迟堆 无界 定时任务

S05-B05 的实测(core 2 + ArrayBlockingQueue(2) → 第 5 个被拒)就是"有界队列"的直接后果。


5. 五个误区

误区 真相
"CHM 用一把锁" JDK 8+ 用 CAS + 桶级锁
"CHM 完全无锁" 写冲突时仍会锁桶
"COW 适合所有读多写少" 写一次复制全数组,数据大时很贵
"LinkedBlockingQueue 有界" 默认无界(Integer.MAX_VALUE)
"synchronizedMap 够用了" 全表锁,吞吐差

6. 自检

  1. CHM 在 JDK 7 与 8 的并发策略差异?为什么废弃分段锁?
  2. CHM 读操作为什么不加锁?
  3. COW 的适用边界是什么?
  4. ArrayBlockingQueue 与 LinkedBlockingQueue 的关键差别?
  5. SynchronousQueue 的容量是多少?用在哪?

7. 下一篇

S05-J03 · 异步编排 CompletableFuture

容器讲完,下一篇讲"把异步任务串起来":实测两个 300ms 任务并行只要 361ms,allOf 两个 200ms 任务只要 204ms。


本篇属于系列《S05 · Java 并发与 JVM》。旧文来源:A-1588/1597/824/1591/835/836;扩展点 E-S05-009。

S05-J02 · 并发容器:CHM、阻塞队列、COW
https://www.clxhxhhr.top/posts/5248/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。