java多线程安全集合

Java 为高并发场景专门设计的高性能线程安全集合。它们各自采用了不同的并发控制策略,适用于不同的场景。下面逐一介绍它们的实现原理、特点和适用场景。

介绍:这些线程安全的并发集合分别对应以下线程不安全的集合类:

线程安全类 对应线程不安全类 说明
ConcurrentHashMap HashMap 无序键值对,高并发场景替代 HashMap 或 Hashtable
ConcurrentSkipListMap TreeMap 有序键值对(基于跳表),高并发场景替代 TreeMap
ConcurrentSkipListSet TreeSet 有序元素集(底层基于 ConcurrentSkipListMap),替代 TreeSet
CopyOnWriteArrayList ArrayList 读多写少场景替代 ArrayList,避免 ConcurrentModificationException
CopyOnWriteArraySet HashSet 读多写少场景替代 HashSet(底层使用 CopyOnWriteArrayList 实现)

1. ConcurrentHashMap

底层实现

  • JDK 1.7 :采用 分段锁(Segment) 技术,将整个 Map 分成多个 Segment,每个 Segment 独立加锁,允许多个线程同时操作不同 Segment。
  • JDK 1.8+ :取消分段锁,改用 CAS + synchronized 对节点进行更细粒度的控制。底层数据结构与 HashMap 类似(数组 + 链表 + 红黑树),写操作只锁定当前操作的桶(或树节点),读操作几乎不加锁(使用 volatile 保证可见性)。

特点

  • 高并发读写,吞吐量远高于 Hashtable 或 Collections.synchronizedMap。
  • 不允许 null 键或值。
  • 提供原子性复合操作:putIfAbsent()、remove()、replace() 等。
  • 迭代器是 弱一致性 (不会抛出 ConcurrentModificationException,但遍历时可能不反映最新修改)。

适用场景

  • 高并发环境下的大规模 Map 操作,是 首选的并发 Map 实现。

2. ConcurrentSkipListMap

底层实现

基于 跳表(Skip List) 数据结构,是一种以空间换时间的并发有序 Map。跳表通过多层索引实现近似二分查找,插入、删除、查找的平均时间复杂度为 O(log n) 。

特点

  • 线程安全,支持高并发读写。
  • 保持键的有序性 ,实现 ConcurrentNavigableMap 接口,提供了 subMap()、headMap()、tailMap() 等视图方法。
  • 并发控制采用 CAS 和锁(在跳表节点层面精细控制),性能优秀。
  • 不允许 null 键或值。

适用场景

  • 需要 有序且高并发 的 Map,例如实现并发缓存、排行榜、范围查询等。
  • 是 TreeMap 的并发替代品。

3. ConcurrentSkipListSet

底层实现

本质上是一个 ConcurrentSkipListMap 的包装 ,所有元素作为 Map 的键,值统一为 Boolean.TRUE。

特点

  • 线程安全、有序(按自然顺序或自定义 Comparator 排序)。
  • 支持高并发读写。
  • 迭代器是弱一致性。

适用场景

  • 需要 有序且高并发 的 Set,例如需要快速判断元素是否存在、保持元素有序,且允许多线程并发访问。

4. CopyOnWriteArrayList

底层实现

采用 写时复制(Copy-On-Write) 策略:

  • 内部维护一个 volatile 数组作为存储。
  • 读操作 (get()、iterator())直接访问当前数组,不加锁,性能极高。
  • 写操作 (add()、set()、remove())先复制一份新数组,在新数组上修改,然后将数组引用指向新数组。复制过程中,读操作仍可并发访问旧数组,保证读线程不被阻塞。

特点

  • 读操作无锁,写操作因复制数组而开销较大(适合读多写少的场景)。
  • 迭代器是 快照 风格,创建后不会受后续修改影响,永远不会抛出 ConcurrentModificationException。
  • 内存占用较高(写操作会临时产生两份数组)。

适用场景

  • 读远多于写 的集合,例如配置信息、监听器列表、缓存等。

5. CopyOnWriteArraySet

底层实现

直接 包装 CopyOnWriteArrayList ,所有操作委托给内部的 CopyOnWriteArrayList。

特点

  • 继承 AbstractSet,元素唯一性通过内部 List 的 addIfAbsent() 保证。
  • 具备与 CopyOnWriteArrayList 相同的读写特性:读无锁、写复制。
  • 由于底层是 List,contains() 操作是 O(n) 复杂度(相对于 HashSet 的 O(1))。

适用场景

  • 与 CopyOnWriteArrayList 类似,适用于 读多写少、且元素唯一 的场景。

对比总结

集合类 数据结构 是否有序 锁机制 读写特性 适用场景
ConcurrentHashMap 数组+链表+红黑树 无序 JDK 1.8+:CAS + synchronized 锁桶/节点 读几乎无锁,写锁粒度细 高并发通用 Map
ConcurrentSkipListMap 跳表 有序 CAS + 节点锁 读写均高效 需要有序、高并发 Map
ConcurrentSkipListSet 跳表(包装 Map) 有序 同 ConcurrentSkipListMap 读写均高效 需要有序、高并发 Set
CopyOnWriteArrayList 数组(写时复制) 保持插入顺序 写时复制(写锁),读无锁 读极快,写慢 读远多于写的 List
CopyOnWriteArraySet 数组(包装 List) 保持插入顺序 同 CopyOnWriteArrayList 读极快,写慢 读远多于写的 Set

选型建议

  • Map :默认首选 ConcurrentHashMap;若需要键有序,使用 ConcurrentSkipListMap。
  • Set :若需高并发且无需排序,可考虑 ConcurrentHashMap 包装的 newKeySet()(JDK 8+,ConcurrentHashMap.newKeySet());若需有序,用 ConcurrentSkipListSet;若读远多于写且元素唯一性要求不高,可用 CopyOnWriteArraySet。
  • List :若读远多于写,用 CopyOnWriteArrayList;否则可考虑用 Collections.synchronizedList 或 ConcurrentLinkedQueue 等替代(但需注意 ConcurrentLinkedQueue 不是 List 接口)。
相关推荐
SL_staff1 分钟前
JVS-APS的7个刚性约束设计:从无限产能幻觉到可执行排产的工程实践
java·spring cloud·全栈
代码山河1 小时前
基本类型转换:自动类型转换与强制类型转换
java·学习·架构·教程·面向对象·项目
Escalating_xu3 小时前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络
程序猿乐锅3 小时前
万字详解Single-flight(单飞模式)
java·开发语言·分布式·后端·学习·single-flight
Java后端的Ai之路3 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
AntsData4 小时前
用 12K+ 条亚马逊评论信号,定位机械键盘下一版该改什么
java·大数据·计算机外设
code2cat4 小时前
【随笔】连续批处理:长短请求怎样在迭代之间补位
java·人工智能·后端·大语言模型·vllm
最强小杰4 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
Flynn Liang4 小时前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
灿飞4 小时前
Kotlin与Java虚拟机六:基础与类型系统:一切皆对象,但对象有代价
java·kotlin