【Java并发编程实战】Java中的JUC容器类详解
并发是Java进阶的分水岭,也是拉开薪资差距的核心能力。
为了帮大家避开碎片化学习误区,我整理了一套
《Java并发编程实战》视频课
覆盖线程基础、JMM底层、锁机制、JUC工具、线程池、并发设计模式与线上实战。
全程原理+源码+实战+调优一站式打通,零基础也能轻松吃透Java并发,彻底摆脱技术瓶颈。
一、JUC容器概览
Java并发包(java.util.concurrent)提供了丰富的线程安全容器类,主要分为以下几类:
JUC容器体系:
├── 阻塞队列 (BlockingQueue)
├── 并发Map (ConcurrentMap)
├── 并发Set (ConcurrentSkipListSet)
├── 并发List (CopyOnWriteArrayList)
├── 并发Deque (BlockingDeque)
└── 其他并发容器
二、阻塞队列(BlockingQueue)
核心特性
- 线程安全 :多线程并发访问安全
- 阻塞操作 :队列空时阻塞取,队列满时阻塞存
- 容量限制 :可指定容量(有界队列)
常用实现类对比表
| 实现类 | 数据结构 | 特性 | 适用场景 |
| ArrayBlockingQueue | 数组 | 有界、FIFO、公平/非公平锁 | 固定大小队列 |
| LinkedBlockingQueue | 链表 | 可选有界、吞吐量高 | 无界/有界队列 |
| PriorityBlockingQueue | 堆 | 优先级排序、无界 | 任务优先级调度 |
| DelayQueue | 优先级队列 | 延迟元素、无界 | 定时任务调度 |
| SynchronousQueue | 无存储 | 直接传递、零容量 | 线程间直接传递 |
| LinkedTransferQueue | 链表 | 高性能、无界 | 高并发生产者-消费者 |
代码示例
import java.util.concurrent.*;
public class BlockingQueueDemo {
// 1. 有界数组队列
BlockingQueue<String> arrayQueue = new ArrayBlockingQueue<>(100);
// 2. 有界链表队列
BlockingQueue<String> linkedQueue = new LinkedBlockingQueue<>(100);
// 3. 无界优先级队列
BlockingQueue<Task> priorityQueue = new PriorityBlockingQueue<>();
// 4. 延迟队列
DelayQueue<DelayedTask> delayQueue = new DelayQueue<>();
// 5. 同步队列(零容量)
BlockingQueue<String> syncQueue = new SynchronousQueue<>();
// 生产者-消费者模式示例
public void producerConsumerDemo() throws InterruptedException {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
// 生产者线程
Thread producer = new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
queue.put(i); // 队列满时阻塞
System.out.println("生产: " + i);
Thread.sleep(100);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
// 消费者线程
Thread consumer = new Thread(() -> {
try {
while (true) {
Integer item = queue.take(); // 队列空时阻塞
System.out.println("消费: " + item);
Thread.sleep(200);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
// 延迟队列示例
static class DelayedTask implements Delayed {
private final String name;
private final long executeTime;
public DelayedTask(String name, long delayMs) {
this.name = name;
this.executeTime = System.currentTimeMillis() + delayMs;
}
@Override
public long getDelay(TimeUnit unit) {
long diff = executeTime - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return Long.compare(this.executeTime, ((DelayedTask) o).executeTime);
}
}
}
三、并发Map(ConcurrentMap)
实现类对比
| 实现类 | 数据结构 | 并发级别 | 特性 |
| ConcurrentHashMap | 数组+链表/红黑树 | 分段锁/CAS | 高并发、线程安全 |
| ConcurrentSkipListMap | 跳表 | 无锁CAS | 有序、支持并发排序 |
ConcurrentHashMap详解
import java.util.concurrent.*;
public class ConcurrentMapDemo {
// 1. 基本用法
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
public static void main(String[] args) {
Main demo = new Main();
demo.demoOperations();
demo.wordCount();
demo.safeStatistics();
demo.concurrentSkipListMapDemo();
}
// 2. 线程安全的操作方法
public void demoOperations() {
// putIfAbsent: 不存在时才放入
map.putIfAbsent("key1", 100);
// compute: 原子性计算
map.compute("key1", (k, v) -> v == null ? 1 : v + 1);
// merge: 合并值
map.merge("key1", 1, Integer::sum);
// forEach: 并发遍历
map.forEach(2, (k, v) -> System.out.println(k + "=" + v));
}
// 3. 统计示例
public void wordCount() {
ConcurrentHashMap<String, Long> wordCount = new ConcurrentHashMap<>();
String[] words = {"hello", "world", "hello", "java"};
for (String word : words) {
wordCount.compute(word, (k, v) -> v == null ? 1 : v + 1);
}
System.out.println(wordCount); // {hello=2, world=1, java=1}
}
// 4. 并发安全统计
public void safeStatistics() {
ConcurrentHashMap<String, AtomicLong> counters = new ConcurrentHashMap<>();
// 线程安全的累加
counters.computeIfAbsent("counter1", k -> new AtomicLong())
.incrementAndGet();
counters.computeIfAbsent("counter1", k -> new AtomicLong())
.incrementAndGet();
System.out.println(counters.get("counter1"));
}
ConcurrentSkipListMap<Integer, String> sortedMap =
new ConcurrentSkipListMap<>();
public void concurrentSkipListMapDemo() {
sortedMap.put(3, "three");
sortedMap.put(1, "one");
sortedMap.put(2, "two");
// 有序遍历
sortedMap.forEach((k, v) -> System.out.println(k + "=" + v));
// 输出: 1=one, 2=two, 3=three
// 范围查询
ConcurrentNavigableMap<Integer, String> subMap =
sortedMap.subMap(1, 3); // 1 <= key < 3
subMap.forEach((k, v) -> System.out.println(k + "=" + v));
}
}
四、并发List和Set
CopyOnWriteArrayList
写时复制(Copy-On-Write)机制:
1. 读取:直接读取当前数组(无锁)
2. 写入:复制原数组 → 修改新数组 → 替换引用
3. 删除:同样需要复制新数组
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Iterator;
public class CopyOnWriteListDemo {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
public void demo() {
// 添加元素(加锁复制)
list.add("element1");
list.add("element2");
// 迭代(使用快照,线程安全)
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
// 迭代过程中可以修改list,不影响当前迭代
list.add("newElement"); // 不会导致ConcurrentModificationException
}
}
}
CopyOnWriteArraySet
┌─────────────────────────────────────────────────────┐
│ 性能特征对比 │
├──────────────┬─────────────────┬───────────────────┤
│ 操作类型 │ CopyOnWriteArraySet │ HashSet │
├──────────────┼─────────────────┼───────────────────┤
│ 添加元素 │ O(n) - 慢 │ O(1) - 快 │
│ 删除元素 │ O(n) - 慢 │ O(1) - 快 │
│ 查找元素 │ O(n) - 慢 │ O(1) - 快 │
│ 遍历操作 │ O(n) - 快 │ O(n) - 快 │
│ 内存占用 │ 较高 │ 较低 │
│ 迭代器创建 │ 快 │ 快 │
└──────────────┴─────────────────┴───────────────────┘
性能影响说明:
• CopyOnWriteArraySet 写操作慢:因为需要复制整个数组
• CopyOnWriteArraySet 读操作快:因为不需要加锁
• HashSet 所有操作都快:基于哈希表实现
• 但HashSet线程不安全,需要额外同步开销
import java.util.concurrent.CopyOnWriteArraySet;
public class CopyOnWriteSetDemo {
// CopyOnWriteArraySet 迭代器 - 弱一致性
Set<String> cowSet = new CopyOnWriteArraySet<>(Arrays.asList("A", "B", "C"));
Iterator<String> it1 = cowSet.iterator();
// 此时修改集合
cowSet.add("D"); // 创建新数组,旧迭代器仍看到旧数据
// 迭代器遍历的是创建时的快照
while (it1.hasNext()) {
System.out.println(it1.next()); // 输出:A, B, C(看不到D)
}
// HashSet 迭代器 - Fail-Fast
Set<String> hashSet = new HashSet<>(Arrays.asList("A", "B", "C"));
Iterator<String> it2 = hashSet.iterator();
try {
hashSet.add("D"); // 修改集合
while (it2.hasNext()) {
System.out.println(it2.next()); // 抛出ConcurrentModificationException
}
} catch (ConcurrentModificationException e) {
System.out.println("检测到并发修改!");
}
}
ConcurrentSkipListSet
import java.util.concurrent.ConcurrentSkipListSet;
public class ConcurrentSkipListSetDemo {
ConcurrentSkipListSet<Integer> sortedSet = new ConcurrentSkipListSet<>();
public void demo() {
sortedSet.add(3);
sortedSet.add(1);
sortedSet.add(2);
// 有序遍历
for (Integer num : sortedSet) {
System.out.println(num); // 1, 2, 3
}
// 范围查询
ConcurrentNavigableSet<Integer> subset = sortedSet.subSet(1, 3);
}
}
五、并发Deque(双端队列)
实现类对比
| 实现类 | 特性 | 适用场景 |
| LinkedBlockingDeque | 有界/无界、线程安全 | 工作窃取、双端操作 |
| ConcurrentLinkedDeque | 无界、无锁 | 高并发、CAS操作 |
public class AddOperations {
public static void main(String[] args) throws InterruptedException {
BlockingDeque<Integer> deque = new LinkedBlockingDeque<>(3);
// 1. addFirst/addLast - 抛出异常
deque.addFirst(1); // 添加到头部
deque.addLast(2); // 添加到尾部
System.out.println(deque); // [1, 2]
// 2. offerFirst/offerLast - 返回布尔值
boolean success = deque.offerFirst(0);
System.out.println("添加成功: " + success); // true
success = deque.offerLast(3); // 队列已满
System.out.println("添加成功: " + success); // false
// 3. putFirst/putLast - 阻塞等待
new Thread(() -> {
try {
Thread.sleep(1000);
deque.takeFirst(); // 消费一个元素
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
deque.putFirst(-1); // 阻塞直到有空间
System.out.println("添加完成");
// 4. offerFirst/offerLast 带超时
boolean added = deque.offerLast(4, 2, TimeUnit.SECONDS);
System.out.println("超时添加结果: " + added);
}
}
六、其他并发容器
ConcurrentLinkedDeque
import java.util.concurrent.ConcurrentLinkedDeque;
public class ConcurrentDequeDemo {
ConcurrentLinkedDeque<String> deque = new ConcurrentLinkedDeque<>();
public void demo() {
// 双端操作
deque.addFirst("first");
deque.addLast("last");
String first = deque.pollFirst();
String last = deque.pollLast();
}
}
七、性能对比与选择指南
性能对比表
| 容器类 | 读性能 | 写性能 | 内存占用 | 适用场景 |
| ConcurrentHashMap | 高 | 高 | 中 | 高并发键值存储 |
| CopyOnWriteArrayList | 极高 | 极低 | 高 | 读多写极少 |
| ConcurrentLinkedQueue | 高 | 高 | 低 | 高并发队列 |
| ArrayBlockingQueue | 中 | 中 | 低 | 固定大小队列 |
| LinkedBlockingQueue | 中 | 高 | 中 | 通用阻塞队列 |
选择指南
public class ContainerSelectionGuide {
// 场景1:高并发缓存
// ✅ 推荐:ConcurrentHashMap
ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();
// 场景2:读多写少的监听器列表
// ✅ 推荐:CopyOnWriteArrayList
CopyOnWriteArrayList<Listener> listeners = new CopyOnWriteArrayList<>();
// 场景3:任务队列(生产者-消费者)
// ✅ 推荐:LinkedBlockingQueue
BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
// 场景4:延迟任务调度
// ✅ 推荐:DelayQueue
DelayQueue<DelayedTask> delayQueue = new DelayQueue<>();
// 场景5:线程池工作队列
// ✅ 推荐:SynchronousQueue(直接传递)
ExecutorService executor = new ThreadPoolExecutor(
10, 10, 0L, TimeUnit.MILLISECONDS,
new SynchronousQueue<>() // 直接传递任务给线程
);
// 场景6:需要排序的并发集合
// ✅ 推荐:ConcurrentSkipListMap/Set
ConcurrentSkipListMap<Integer, String> sortedMap = new ConcurrentSkipListMap<>();
}
并发是Java进阶的分水岭,也是拉开薪资差距的核心能力。
为了帮大家避开碎片化学习误区,我整理了一套
《Java并发编程实战》视频课
覆盖线程基础、JMM底层、锁机制、JUC工具、线程池、并发设计模式与线上实战。
全程原理+源码+实战+调优一站式打通,零基础也能轻松吃透Java并发,彻底摆脱技术瓶颈。
更多推荐


所有评论(0)