并发容器
并发容器位于 java.util.concurrent 包,专为多线程环境设计。
ConcurrentHashMap
特点
- JDK 7:分段锁(16 个 Segment)
- JDK 8+:CAS + synchronized(桶级别锁)
- 读操作无锁,写操作只锁单个桶
- 不允许 null 键值
使用示例
Java
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
// 基本操作
map.put("key", 1);
map.get("key");
map.remove("key");
// 原子复合操作
map.putIfAbsent("key", 1); // 不存在才放入
map.replace("key", 1, 2); // 值为 1 才替换为 2
map.computeIfAbsent("key", k -> 1); // 不存在才计算放入
map.merge("key", 1, (old, v) -> old + v);
// 批量操作
map.forEach((k, v) -> System.out.println(k + ":" + v));
map.replaceAll((k, v) -> v * 2);
ConcurrentHashMap vs Hashtable
| 特性 | Hashtable | ConcurrentHashMap |
|---|---|---|
| 锁机制 | 全表锁 | 分段锁/CAS |
| 读操作 | 加锁 | 无锁 |
| 性能 | 低 | 高 |
CopyOnWriteArrayList
特点
- 写时复制:每次写操作复制整个数组
- 读操作无锁,性能极高
- 写操作开销大
- 适合读多写少
使用示例
Java
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
// 读操作(无锁)
String s = list.get(0);
for (String item : list) {
// 遍历无需加锁
}
// 写操作(复制整个数组)
list.add("newElement");
list.remove(0);
list.set(0, "updated");
适用场景:事件监听器列表、配置列表等读多写少场景。
CopyOnWriteArrayList vs ArrayList
| 操作 | ArrayList | CopyOnWriteArrayList |
|---|---|---|
| 读 | 快 | 快(无锁) |
| 写 | 快 | 慢(复制数组) |
| 并发安全 | ❌ 不安全 | ✅ 安全 |
CopyOnWriteArraySet
Java
CopyOnWriteArraySet<String> set = new CopyOnWriteArraySet<>();
// 基于 CopyOnWriteArrayList 实现,自动去重
set.add("A");
set.add("A"); // 重复不会添加
ConcurrentLinkedQueue
无界并发队列,CAS 实现:
Java
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
// 入队
queue.offer("element"); // 无界,不会阻塞
// 出队
String e = queue.poll(); // 空返回 null
String e = queue.peek(); // 查看队头(不移除)
BlockingQueue 阻塞队列
ArrayBlockingQueue
有界阻塞队列:
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);
LinkedBlockingQueue
可选有界阻塞队列:
Java
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);
System.out.println("生产:" + i);
}
} catch (InterruptedException e) {}
}).start();
// 消费者
new Thread(() -> {
try {
while (true) {
String item = queue.take();
System.out.println("消费:" + item);
}
} catch (InterruptedException e) {}
}).start();
ConcurrentSkipListMap/Set
并发排序集合:
Java
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}(排序)
ConcurrentSkipListSet<Integer> set = new ConcurrentSkipListSet<>();
set.add(3);
set.add(1);
System.out.println(set); // [1, 3](排序)
要点总结
- ConcurrentHashMap:分段锁/CAS,高并发 HashMap 替代
- CopyOnWriteArrayList:写时复制,读无锁,读多写少适用
- ConcurrentLinkedQueue:无界并发队列
- BlockingQueue:阻塞队列,生产者-消费者模式
- ConcurrentSkipListMap/Set:并发排序集合
- ConcurrentHashMap 不允许 null 键值
- 高并发用 ConcurrentHashMap,读多写少用 CopyOnWrite
- BlockingQueue 的 put/take 阻塞,offer/poll 非阻塞
📝 发现内容有误?点击此处直接编辑