跳转到主内容
极星编程网:以代码为星,赴技术山海!

比较Collections工具类提供的同步包装器性能

不推荐在高并发或性能敏感场景使用同步包装器,因其采用粗粒度锁导致严重串行化、iterator非线程安全、复合操作无法原子执行;ConcurrentHashMap等java.util.concurrent集合通过分段锁/CAS/无锁算法显著提升性能。 同步包装器(如
Collections.synchronizedList()
、
Collections.synchronizedMap()
等)性能较差,**不推荐在高并发或性能敏感场景使用**。核心问题在于粗粒度锁和缺乏并发语义支持。 锁粒度太粗,严重串行化 每个同步包装器内部持有一个对象锁(通常是集合自身),所有方法(
get
、
put
、
size
、
iterator
等)都用同一把锁保护。这意味着: 即使两个线程操作完全不相交的键(如 HashMap 中不同桶),也会相互阻塞
iterator()
返回的迭代器本身不是线程安全的,遍历时仍需手动同步整个集合 复合操作(如“检查是否存在再插入”)无法原子执行,必须额外加锁,易出错 与 java.util.concurrent 替代品对比明显 现代并发集合专为多线程设计,性能提升显著:
ConcurrentHashMap
使用分段锁(JDK 7)或 CAS + synchronized 桶锁(JDK 8+),读操作无锁,写操作仅锁单个桶
CopyOnWriteArrayList
适合读多写少场景,读不加锁,写时复制底层数组
ConcurrentLinkedQueue
基于无锁算法(CAS),吞吐量远高于
Collections.synchronizedList(new LinkedList())
实际开销不可忽视 基准测试(JMH)常见结果: 单线程下,同步包装器比原始集合慢 2–5 倍(方法调用+同步开销) 2 线程并发写入
HashMap
:同步包装器吞吐量可能不足
ConcurrentHashMap
的 1/10 迭代场景中,同步包装器需显式
synchronized(list) { for(...) {...} }
,而
CopyOnWriteArrayList
直接 for-each 即可 适用场景非常有限 仅在以下情况可考虑同步包装器: 线程数极少(如 1–2 个后台线程)、并发度低、且集合生命周期短 作为临时过渡方案,尚未重构为并发集合 需要快速包装遗留代码中的非线程安全集合,且确认访问模式简单(如只读或单点写入) 但即便如此,也建议优先选用
java.util.concurrent
中对应类型,或使用
ImmutableList.copyOf()
等不可变封装。

相关文章