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

并发集合

并发集合位于 java.util.concurrent 包,专为多线程并发访问设计。

同步集合 vs 并发集合

类型代表类特点性能
同步集合Vector、Hashtable、Collections.synchronizedXxx全表锁
并发集合ConcurrentHashMap、CopyOnWriteArrayList分段锁/CAS

同步集合问题:全表一把锁,并发度低,遍历需手动加锁。

ConcurrentHashMap

JDK 7 实现

  • 分段锁(Segment),默认 16 个段
  • 每个段独立锁,并发度高

JDK 8+ 实现

  • CAS + synchronized
  • 锁粒度更细(桶级别)
  • 读操作完全无锁

使用示例

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

// 基本操作
map.put("张三", 25);
map.get("张三");              // 无锁读取
map.remove("张三");

// 原子复合操作
map.putIfAbsent("李四", 30);  //不存在才放入
map.replace("张三", 25, 26);  // 值为 25 才替换
map.compute("张三", (k, v) -> v + 1);  // 计算
map.merge("张三", 1, (old, newV) -> old + newV);

// 批量操作(Java 8+)
map.forEach((k, v) -> System.out.println(k + ":" + v));
map.replaceAll((k, v) -> v * 2);

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

ConcurrentHashMap vs Hashtable

特性HashtableConcurrentHashMap
锁机制全表锁分段锁/CAS
读操作加锁无锁
null键值不允许不允许
性能

CopyOnWriteArrayList

特点

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

使用示例

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

// 读操作(无锁)
String s = list.get(0);
for (String item : list) {
    // 遍历无需加锁
}

// 写操作(复制整个数组)
list.add("新元素");
list.remove(0);
list.set(0, "修改");

// 迭代器弱一致性:迭代期间不影响其他线程
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    System.out.println(it.next());  // 即使其他线程修改,迭代继续
}

适用场景:事件监听器列表、配置列表等读多写少场景。不适合写频繁场景。

CopyOnWriteArraySet

Java
CopyOnWriteArraySet<String> set = new CopyOnWriteArraySet<>();
// 基于 CopyOnWriteArrayList 实现的去重 Set
set.add("A");
set.add("A");  // 重复不会添加

ConcurrentLinkedQueue

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

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

// 入队
queue.offer("元素");          // 无界队列,不会阻塞

// 出队
String item = queue.poll();   // 空返回 null
String item = queue.peek();   // 查看队头,不移除

适用场景:高并发队列,不需要阻塞功能。

BlockingQueue 阻塞队列

ArrayBlockingQueue

有界阻塞队列(数组实现):

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

// 阻塞操作
queue.put("元素");            // 队满阻塞等待
String item = queue.take();   // 队空阻塞等待

// 非阻塞操作(带超时)
boolean success = queue.offer("元素", 3, TimeUnit.SECONDS);
String item = queue.poll(3, TimeUnit.SECONDS);

LinkedBlockingQueue

可选有界阻塞队列(链表实现):

Java
// 无界(默认 Integer.MAX_VALUE)
LinkedBlockingQueue<String> unbounded = new LinkedBlockingQueue<>();

// 有界
LinkedBlockingQueue<String> bounded = new LinkedBlockingQueue<>(100);

BlockingQueue 类型

类型特点
ArrayBlockingQueue有界,数组,公平可选
LinkedBlockingQueue可选有界,链表
PriorityBlockingQueue无界,优先级排序
DelayQueue无界,延迟元素
SynchronousQueue无缓冲,直接传递

生产者-消费者示例

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

// 生产者
new Thread(() -> {
    try {
        for (int i = 0; i < 100; i++) {
            queue.put("item-" + i);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}).start();

// 消费者
new Thread(() -> {
    try {
        while (true) {
            String item = queue.take();
            System.out.println("消费:" + item);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}).start();

ConcurrentSkipListMap/Set

跳表实现的并发排序集合:

Java
// 并发排序 Map
ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
map.put(3, "C");
map.put(1, "A");
map.put(2, "B");
System.out.println(map);  // {1=A, 2=B, 3=C}(排序)

// 并发排序 Set
ConcurrentSkipListSet<Integer> set = new ConcurrentSkipListSet<>();
set.add(3);
set.add(1);
set.add(2);
System.out.println(set);  // [1, 2, 3](排序)

要点总结

  • ConcurrentHashMap:分段锁/CAS,高并发 HashMap 替代
  • CopyOnWriteArrayList:写时复制,读无锁,读多写少适用
  • ConcurrentLinkedQueue:无界并发队列,CAS 实现
  • BlockingQueue:阻塞队列,生产者-消费者模式
  • ConcurrentSkipListMap/Set:并发排序集合
  • ConcurrentHashMap 不允许 null 键值
  • 选择原则:高并发用 ConcurrentHashMap,读多写少用 CopyOnWrite,队列用 BlockingQueue

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

← 上一篇 Set 接口与实现
下一篇 → 泛型与集合
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

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

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