JAVA线程安全的集合类分类
1. 传统同步集合类(早期实现,性能较低)
- Vector
- 动态数组实现,所有方法通过
synchronized
同步锁保证线程安全。
- 动态数组实现,所有方法通过
- Stack
- 继承自
Vector
,实现后进先出(LIFO)堆栈,同步锁机制与Vector
相同。
- 继承自
- Hashtable
- 基于哈希表,所有方法通过
synchronized
同步锁实现线程安全。
- 基于哈希表,所有方法通过
注意:上述类因锁粒度过大(全局锁),高并发场景下性能较差,已逐渐被并发包替代。
2. 并发包高效线程安全集合(java.util.concurrent
)
- ConcurrentHashMap
- 分段锁(Java 7)或
CAS + synchronized
(Java 8+)优化锁粒度,支持高并发读写。
- 分段锁(Java 7)或
- CopyOnWriteArrayList / CopyOnWriteArraySet
- 写时复制新数组,读操作无锁,适用于 读多写少 场景。
- ConcurrentLinkedQueue
- 基于链表的无锁队列,通过
CAS
实现高并发线程安全。
- 基于链表的无锁队列,通过
- ConcurrentSkipListMap
- 基于跳表实现的有序映射表,支持并发高效操作。
3. 阻塞队列(BlockingQueue
)
- ArrayBlockingQueue
- 基于数组的有界队列,按
FIFO
排序,支持公平锁。
- 基于数组的有界队列,按
- LinkedBlockingQueue
- 基于链表的可选有界/无界队列,默认无界。
- PriorityBlockingQueue
- 无界队列,支持优先级排序。
- SynchronousQueue
- 不存储元素,直接传递任务,适用于线程池任务调度。
ArrayBlockingQueue
和 LinkedBlockingQueue
等实现类内部使用 ReentrantLock
保证共享资源的互斥访问。LinkedBlockingQueue
采用 双锁分离策略(putLock
和 takeLock
),分别控制入队和出队操作,减少锁竞争,提高并发性能。
4. 同步包装器(Collections
工具类)
- 实现方式
Collections.synchronizedList()
、synchronizedSet()
、synchronizedMap()
包装非线程安全集合(如ArrayList
、HashMap
),所有方法添加synchronized
锁。
- 注意事项
- 组合操作(如遍历、条件判断)需显式加锁,否则仍可能引发并发问题。
选型建议
场景 | 推荐集合类 | 理由 |
---|---|---|
高并发读写 Map | ConcurrentHashMap | 分段锁/CAS 优化,性能远超 Hashtable |
读多写少的 List/Set | CopyOnWriteArrayList /CopyOnWriteArraySet | 写时复制,无锁读 |
生产者-消费者模型 | ArrayBlockingQueue /LinkedBlockingQueue | 阻塞机制简化线程协作 |
简单同步需求(兼容旧代码) | Collections.synchronizedXXX() | 快速包装非线程安全集合,需注意显式锁控制 |
总结
Java 线程安全集合类可分为 传统同步类、并发包高效类、阻塞队列 和 同步包装器。优先推荐使用 ConcurrentHashMap
、CopyOnWriteArrayList
和 BlockingQueue
等并发包实现,兼顾性能与线程安全;传统类(如 Vector
)和同步包装器适用于兼容性场景,但需注意性能开销。