当前位置: 首页 > news >正文

Java中的JUC容器类详解

一、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多线程与并发编程原理详解》​

http://www.jsqmd.com/news/810634/

相关文章:

  • 昆明闲置钻石回血避坑|5家正规平台实测,拒绝当冤种 - 奢侈品回收测评
  • 初次使用Taotoken从注册到完成第一个API调用的全流程
  • 2026年毕业生收藏:论文AI率太高怎么办?教你精准使用降AI率工具一键降ai - 降AI实验室
  • ModelSim入门实战(四): 参数化测试、自动比对与报告生成
  • 【Qlib框架】因子定义层及整体框架(alpha因子库+数据预处理+模型预测+IC分析+回测backtestdaily+风险分析+交易质量分析)
  • Bilibili视频下载终极指南:如何三步搞定大会员4K视频本地化
  • ChatGPT开发者实战指南:从API集成到应用部署的完整资源导航
  • JT808协议实战:用JTXQ模拟终端复现车道偏离报警全流程(附日志分析)
  • 2026哪个机构主任护师通过率高?过来人实测对比,避坑必看 - 医考机构品牌测评专家
  • 从开发者反馈看Taotoken标准OpenAI协议兼容性的实际表现
  • 088、Python网络服务开发:HTTP服务器
  • 2026年靠谱线下红娘机构推荐:合规婚恋服务机构选型与场景适配深度分析 - 产业观察网
  • 【题解】CF1603D Artistic Partition
  • 从零到一:51单片机蓝牙遥控车实战指南(附避坑要点)
  • 前端超能力:让浏览器听你指挥
  • 2026年5月盘点:3家主任护师备考机构通过率排名,第1名断层领先 - 医考机构品牌测评专家
  • SOS-dp
  • FPGA新手避坑指南:Quartus II 13.1下NCO IP核的完整配置与授权实战
  • 2026江苏主任护师考试培训机构实力排名:3家培训机构全方位评测 - 医考机构品牌测评专家
  • 每日算法快闪赛
  • 百达翡丽鹦鹉螺出手前必看:广州五家门店实测谁更实在 - 奢侈品回收测评
  • 使用Helm Chart在Kubernetes部署高可用authentik身份认证中心
  • 089、Python玩转硬件:用pyserial搞定串口通信那些坑
  • 对比直接使用官方 API 观察到的 Taotoken 路由容错效果
  • 2026年丽水黄金回收哪家靠谱?五店深度测评与打分 - 生活测评君
  • GPU时代的有用浪费:从效率至上到算力换一切的工程范式转变
  • Java 21 面试常见问题汇总
  • 在持续集成环境中集成 Taotoken CLI 实现自动化配置与密钥轮换
  • 从0到1,构建你的第一个AI Agent:核心原理与实战指南
  • Cursor Pro破解终极指南:开源工具cursor-free-vip实现AI编程助手永久免费使用