并发容器的本质不是“线程安全”四个字而是在不同读写比例下怎么用不同的数据结构把性能与一致性做到可控这篇按“选型 - 原理 - 坑 - 排查”的结构讲ConcurrentHashMapCHMCopyOnWriteArrayListBlockingQueue阻塞队列1. ConcurrentHashMap你至少要讲清 3 个点1.1 为什么 HashMap 线程不安全扩容/链表转换过程中可能出现数据丢失、死循环等问题历史版本更明显1.2 CHM 怎么做到高并发你可以按版本讲JDK7分段锁SegmentJDK8CAS synchronized桶级锁 红黑树工程上你只需要把结论讲清锁粒度从“全表”降到“桶/节点”并在大部分情况下走 CAS 快路径1.3 put/get 的性能特点get 大多无锁put 在冲突桶上加锁synchronized2. CHM 的常见坑把 CHM 当成“强一致 map”并发下 size/遍历是弱一致computeIfAbsent 里做慢操作可能导致桶锁长时间占用把大对象塞进去内存压力与 GC 压力上升排查建议如果发现某个 key 热点更新考虑分段 key 或引入 LongAdder 聚合3. CopyOnWriteArrayList读多写少的利器核心机制写操作时复制一份新数组修改后再替换引用读操作不加锁直接读当前数组引用适用场景读多写少例如白名单、配置快照、监听器列表不适用写频繁复制数组成本很高4. BlockingQueue线程池与生产消费的核心组件常见实现ArrayBlockingQueue有界、数组、一个锁公平可选LinkedBlockingQueue可有界也可无界无界风险大SynchronousQueue不存储直接交接DelayQueue延迟任务工程选型需要背压优先有界队列低延迟短任务可考虑 SynchronousQueue配合合理 max5. 阻塞队列常见坑无界队列堆积最终 OOM 或延迟爆炸把阻塞队列当缓存阻塞队列不是缓存更像协调组件生产快于消费需要背压、限流、或扩容消费者6. 线上排查容器导致的性能问题怎么看CPU 高可能是热点 key 自旋/CAS 重试或 computeIfAbsent 慢逻辑RT 抖可能是桶锁竞争、写放大、或队列堆积OOM可能是无界队列、或 map/列表塞了大对象7. 面试追问 QAQCHM 为什么 get 快A读大多无锁依赖 volatile/内存语义保证可见性。QCopyOnWrite 为什么适合读多写少A读无锁写复制数组写成本高。Q阻塞队列和普通队列有什么本质区别A阻塞队列提供阻塞/唤醒语义用于线程协作与背压。8. 面试表达30 秒讲清楚CHM 在 JDK8 主要靠 CAS 桶级锁提高并发度get 大多无锁put 在冲突桶上加锁。CopyOnWrite 写时复制读无锁适合读多写少。BlockingQueue 是线程协作与背压组件选型关键是是否有界、是否允许堆积。9. 总结并发容器选型看读写比例与背压需求CHM 不是强一致结构热点 key 仍可能成为瓶颈CopyOnWrite 写成本高别用错场景阻塞队列有界优先避免无界堆积
并发容器:CHM、CopyOnWrite、阻塞队列的选型与常见坑
并发容器的本质不是“线程安全”四个字而是在不同读写比例下怎么用不同的数据结构把性能与一致性做到可控这篇按“选型 - 原理 - 坑 - 排查”的结构讲ConcurrentHashMapCHMCopyOnWriteArrayListBlockingQueue阻塞队列1. ConcurrentHashMap你至少要讲清 3 个点1.1 为什么 HashMap 线程不安全扩容/链表转换过程中可能出现数据丢失、死循环等问题历史版本更明显1.2 CHM 怎么做到高并发你可以按版本讲JDK7分段锁SegmentJDK8CAS synchronized桶级锁 红黑树工程上你只需要把结论讲清锁粒度从“全表”降到“桶/节点”并在大部分情况下走 CAS 快路径1.3 put/get 的性能特点get 大多无锁put 在冲突桶上加锁synchronized2. CHM 的常见坑把 CHM 当成“强一致 map”并发下 size/遍历是弱一致computeIfAbsent 里做慢操作可能导致桶锁长时间占用把大对象塞进去内存压力与 GC 压力上升排查建议如果发现某个 key 热点更新考虑分段 key 或引入 LongAdder 聚合3. CopyOnWriteArrayList读多写少的利器核心机制写操作时复制一份新数组修改后再替换引用读操作不加锁直接读当前数组引用适用场景读多写少例如白名单、配置快照、监听器列表不适用写频繁复制数组成本很高4. BlockingQueue线程池与生产消费的核心组件常见实现ArrayBlockingQueue有界、数组、一个锁公平可选LinkedBlockingQueue可有界也可无界无界风险大SynchronousQueue不存储直接交接DelayQueue延迟任务工程选型需要背压优先有界队列低延迟短任务可考虑 SynchronousQueue配合合理 max5. 阻塞队列常见坑无界队列堆积最终 OOM 或延迟爆炸把阻塞队列当缓存阻塞队列不是缓存更像协调组件生产快于消费需要背压、限流、或扩容消费者6. 线上排查容器导致的性能问题怎么看CPU 高可能是热点 key 自旋/CAS 重试或 computeIfAbsent 慢逻辑RT 抖可能是桶锁竞争、写放大、或队列堆积OOM可能是无界队列、或 map/列表塞了大对象7. 面试追问 QAQCHM 为什么 get 快A读大多无锁依赖 volatile/内存语义保证可见性。QCopyOnWrite 为什么适合读多写少A读无锁写复制数组写成本高。Q阻塞队列和普通队列有什么本质区别A阻塞队列提供阻塞/唤醒语义用于线程协作与背压。8. 面试表达30 秒讲清楚CHM 在 JDK8 主要靠 CAS 桶级锁提高并发度get 大多无锁put 在冲突桶上加锁。CopyOnWrite 写时复制读无锁适合读多写少。BlockingQueue 是线程协作与背压组件选型关键是是否有界、是否允许堆积。9. 总结并发容器选型看读写比例与背压需求CHM 不是强一致结构热点 key 仍可能成为瓶颈CopyOnWrite 写成本高别用错场景阻塞队列有界优先避免无界堆积