全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-10 9 分钟 ✍️ juanwangdev

线程安全集合

线程安全集合用于多线程并发访问场景,分为同步包装类和并发集合类两大类。

线程安全集合分类

类别代表类特点适用场景
同步包装类Vector、Hashtable、Collections.synchronizedXxx全表锁,性能低低并发场景
并发集合ConcurrentHashMap、ConcurrentLinkedQueue分段锁/CAS,高并发性能好高并发场景
CopyOnWriteCopyOnWriteArrayList、CopyOnWriteArraySet写时复制,读无锁读多写少

同步包装类

Collections.synchronizedXxx

Java
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Set<String> syncSet = Collections.synchronizedSet(new HashSet<>());
Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>());

注意:遍历同步集合需要手动加锁:

Java
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
synchronized (syncList) {  // 遍历时必须加锁
    for (String s : syncList) {
        // 遍历逻辑
    }
}

Vector 和 Hashtable

Java
Vector<String> vector = new Vector<>();       // 同步的 ArrayList
Hashtable<String, String> hashtable = new Hashtable<>(); // 同步的 HashMap

不建议使用:Vector 和 Hashtable 是遗留类,性能差,推荐使用并发集合替代。

ConcurrentHashMap

特点

  • JDK 7:分段锁(Segment),16 个段独立锁
  • JDK 8+:CAS + synchronized,更细粒度(桶级别)
  • 读操作无锁,写操作只锁单个桶
  • 性能远优于 Hashtable

使用示例

Java
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

// 基本操作
map.put("key", 1);
map.get("key");
map.remove("key");

// 原子复合操作
map.putIfAbsent("key", 1);           //不存在才放入
map.computeIfAbsent("key", k -> 1);  // 不存在才计算放入
map.replace("key", 1, 2);            // 值为1才替换为2

注意:ConcurrentHashMap 不允许 null 键或 null 值。

CopyOnWriteArrayList

特点

  • 写时复制:每次写操作复制整个数组
  • 读操作无锁,性能极高
  • 写操作开销大,适合读多写少

使用示例

Java
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();

// 读操作(无锁,快)
String s = list.get(0);

// 写操作(复制整个数组,慢)
list.add("newElement");
list.remove(0);
list.set(0, "updated");

适用场景

  • 读多写少:如事件监听器列表、配置列表
  • 遍历频繁:遍历不需要加锁
  • 不适用:写操作频繁的场景

ConcurrentLinkedQueue

无界并发队列,基于 CAS 实现:

Java
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

queue.offer("element");  // 入队
String e = queue.poll(); // 出队(空返回null)
String e = queue.peek(); // 查看队头(不移除)

BlockingQueue 阻塞队列

Java
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(100);

// 阻塞操作
queue.put("element");     // 队满阻塞
String e = queue.take();  // 队空阻塞

// 非阻塞操作(带超时)
queue.offer("element", 3, TimeUnit.SECONDS);  // 超时入队
String e = queue.poll(3, TimeUnit.SECONDS);   // 超时出队

要点总结

  • 同步包装类:全表锁,性能低,遍历需手动加锁
  • ConcurrentHashMap:分段锁/CAS,高并发性能好,推荐使用
  • CopyOnWriteArrayList:写时复制,读无锁,适合读多写少
  • ConcurrentLinkedQueue:无界并发队列,基于 CAS
  • BlockingQueue:阻塞队列,适合生产者-消费者模式
  • 选择原则:高并发用 ConcurrentHashMap,读多写少用 CopyOnWrite

📝 发现内容有误?点击此处直接编辑

← 上一篇 原子类 Atomic
下一篇 → Java中介者模式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库