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

Java高并发编程(2)

以下是针对并发编程中线程安全 List、ConcurrentLinkedQueue、BlockingQueue 及跳表的详细解析,结合原理、使用场景和代码示例进行说明:


一、线程安全 List 的实现类及使用场景

  1. CopyOnWriteArrayList

    • 原理:采用写时复制(Copy-On-Write),每次修改操作(如 addset)会复制底层数组,在新数组上操作,避免读写冲突。
    • 适用场景读多写极少(如缓存、配置管理)。
    • 优点:读操作无锁,迭代器弱一致性(不抛 ConcurrentModificationException)。
    • 缺点:写操作昂贵(复制整个数组),内存占用高。
    • 示例
      List<String> list = new CopyOnWriteArrayList<>();
      list.add("A"); // 写时复制
      String item = list.get(0); // 读操作无锁
      
  2. Collections.synchronizedList()

    • 原理:通过 synchronized 关键字对所有方法加锁(如 getadd)。
    • 适用场景:低并发写入场景。
    • 缺点:锁粒度大,高并发时性能差;迭代时需手动加锁避免 ConcurrentModificationException
    • 示例
      List<String> syncList = Collections.synchronizedList(new ArrayList<>());
      synchronized(syncList) { // 迭代时手动加锁for (String s : syncList) { ... }
      }
      
  3. 其他线程安全方案

    • Vector:历史遗留类,所有方法用 synchronized 修饰,性能较差,不推荐使用。
    • ConcurrentHashMap + List:按 Key 分区存储,减少锁竞争,适合大数据量分类存储。

二、ConcurrentLinkedQueue(无锁并发队列)

核心特性
  • 非阻塞无锁设计:基于 CAS(Compare-And-Swap)实现线程安全,无锁竞争。
  • 无界队列:动态扩展链表节点,理论容量无限(受限于内存)。
  • FIFO 顺序:严格保证先进先出。
使用场景
  • 高并发写入:如日志收集、事件总线(生产者远多于消费者)。
  • 非阻塞任务队列:需要高吞吐且无需等待的场景。
常用方法
方法作用返回值
offer(e)插入元素(尾部)true(总是成功)
poll()移除并返回头部元素(队列空则返回 null元素或 null
peek()查看头部元素(不移除)元素或 null
isEmpty()判断队列是否为空boolean
size()O(n) 时间复杂度,慎用!队列元素数量
代码示例
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
// 生产者线程
queue.offer("Task1");
// 消费者线程
String task = queue.poll();
if (task != null) {System.out.println("Processed: " + task);
}

注意size() 方法需遍历链表,性能差,避免高频调用。


三、BlockingQueue(阻塞队列)

核心特性
  • 阻塞操作
    • 队列空时,消费者调用 take() 阻塞等待;
    • 队列满时,生产者调用 put() 阻塞等待。
  • 有界/无界ArrayBlockingQueue 固定大小,LinkedBlockingQueue 可选有界(默认 Integer.MAX_VALUE)。
  • 线程安全:内部通过 ReentrantLock 实现同步。
使用场景
  • 生产者-消费者模式:如线程池任务队列(ThreadPoolExecutor 默认使用 LinkedBlockingQueue)。
  • 流量控制:通过有界队列限制系统负载(如防止内存溢出)。
常用实现类
实现类特点
ArrayBlockingQueue数组实现,固定容量,公平锁可选
LinkedBlockingQueue链表实现,可选容量,吞吐量高
Prio
http://www.lryc.cn/news/590560.html

相关文章:

  • beautiful-react-hooks库——入门实践常用hook详解
  • React之旅-09 useMemo,优化计算性能的利器
  • React 源码7:Lane、React和schedule优先级转换
  • WPF 多窗口分文件实现方案
  • 【MAC】nacos 2.5.1容器docker安装
  • QT——事件系统详解
  • 多语言json文件内\n换行不生效问题
  • React -自定义hooks - 封装双向数据绑定
  • React 中 props 的最常用用法精选+useContext
  • H3CNE综合实验之机器人
  • Antd中使用Table集成 react-resizable实现可伸缩列
  • PowerJob集群机器数为0问题
  • 深度剖析 TDMQ RabbitMQ 版经典队列底层存储机制
  • vue页面不销毁的情况下再返回,总是执行created,而不触发 activated
  • QOpenGLWidget自定义控件— 2D点云显示(支持平移、放缩、绘制网格)
  • SpringBoot集成Minio存储文件,开发图片上传等接口
  • 【c++深入系列】:万字详解list(附模拟实现的list源码)
  • 【Fedora 42】Linux内核升级后,鼠标滚轮失灵,libinput的锅?
  • 开源 python 应用 开发(六)网络爬虫
  • ubuntu中拷贝docker容器中的文件到宿主机
  • IKE学习笔记
  • K8s 自定义调度器 Part1:通过 Scheduler Extender 实现自定义调度逻辑
  • AI产品经理面试宝典第28天:自动驾驶与智慧交通融合面试题与答法
  • Xshell 7.0.0111p.exe 下载安装教程 - 详细步骤指南(包含安装包)
  • Kotlin获取集合中的元素操作
  • Kotlin比较接口
  • 《工程伦理》分析报告二 无人驾驶
  • 利用pdfjs实现的pdf预览简单demo(包含翻页功能)
  • 用AI做带货视频评论分析进阶提分【Datawhale AI 夏令营】
  • Windows11怎样禁止应用开机启动