浅谈集合之线程安全方案
List
一般方法
-
自定义 ArrayList 子类:手动同步/加锁,复杂度高。
-
Vector(Java 1.0):
- 特点:大量方法签名使用 synchronized 对象锁(全局锁)。
- 说明:性能差。
-
Collections.synchronizedList:(Java 1.2)同步代理类
- 特点:引入成员变量 mutex 对象锁,synchronized(mutex)(全局锁)。
- 说明:性能不是最优。
CopyOnWriteArrayList
(Java 1.5 - JUC)写时复制
- 操作:
- 读:直接读取集合本身,无须加锁与阻塞(不加锁)。
- 写:如增删,需要加锁(避免 copy 多个副本)
- 线程执行写操作时,copy 一份新的数组。
- 对副本执行写操作。
- 修改引用
- 特点:读写分离,延时更新
- 内存使用:写操作会额外产生一份数组,不适合大数据量场景。
- 最终一致性:读操作获取一份快照,不适合实时性高的场景。
Map
一般方法
- Hashtable:(Java 1.0)同 Vector,全局锁。
- Collections.synchronizedMap:同 synchronizedList,全局锁。
ConcurrentHashMap
(JUC)
- Java 1.7-:分段锁
- 将 HashMap 的 Entry 数组拆分为多段(segment)
- segment 是 ReentrantLock 实现类,对 segment 加锁可避免锁表。
- Java 1.8+:CAS + synchronized(锁头结点)