Java 中无锁队列怎么使用 CAS 怎么保证线程安全

落枫大大_2183

落枫大大_2183

2026-10-27

753人浏览

原创

ConcurrentLinkedQueue 用 CAS 配合 volatile 实现无锁线程安全:CAS 更新 tail 和 head 指针,volatile 保证可见性与有序性;size() 非实时,不可用于条件判断,且不支持 null 元素。

java 中无锁队列怎么使用 cas 怎么保证线程安全

Java 中无锁队列(如 ConcurrentLinkedQueue)不靠 synchronized 或 ReentrantLock,而是用 CAS(Compare-And-Swap)配合 volatile 字段实现线程安全。它的核心不是“没同步”,而是把同步逻辑下沉到 CPU 指令级,靠乐观重试代替阻塞等待。

CAS 在队列里具体干了什么

CAS 不是泛泛而谈的机制,它在队列中只作用于两个关键位置:

  • tail 指针更新:入队时,线程尝试把新节点设为当前 tail 的 next;若失败(tail 已被别的线程改过),就先用一次 CAS 把 tail 推进到更靠后的节点,再重试连接
  • head 指针更新:出队时,线程先读 head.next,再 CAS 将 head 指向该 next 节点;若发现 head 已经“卡住”在傀儡节点上,就推进 head 并继续找真实数据节点

为什么光有 CAS 还不够?volatile 是怎么配合的

CAS 操作本身能保证单次更新的原子性,但要让整个队列结构对所有线程可见、不乱序,必须靠 volatile:

Java注释规范Skills
Java注释规范Skills

当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。

下载
  • head 和 tail 字段声明为 volatile,确保每次读取都从主内存拿最新值,写入立即刷回
  • JVM 在 volatile 读写前后插入内存屏障,防止编译器或 CPU 把 item = x 重排到 next = newNode 之后——这会破坏节点发布的安全性
  • Node 内部的 item 和 next 虽未显式加 volatile,但通过 Unsafe.compareAndSetObject 对引用字段的原子操作,间接实现了安全发布

线程安全不是“绝对正确”,而是“弱一致性下的可预测”

无锁队列的线程安全有明确边界,理解这些才能避免误用:

  • offer() 总返回 true,poll() 空时返回 null,但 poll() == null 不代表队列真为空——可能只是当前线程看到的 head 还没推进到位
  • size() 需遍历链表,结果非实时;不能用它做空判断,应优先用 isEmpty()
  • 不允许存 null,否则无法区分“队列空”和“存了个 null”
  • 高并发下多个线程反复 CAS 失败会自旋重试,CPU 使用率可能升高,但不会挂起线程或引发死锁

实际使用时的关键提醒

直接 new 一个 ConcurrentLinkedQueue 很简单,但真正用好它需要避开几个典型坑:

  • 别拿 size() 做条件判断,比如 if (q.size() > 0) q.poll() 是竞态的,应改用 if (!q.isEmpty()) q.poll()
  • 不要在循环里反复调用 size(),尤其在日志缓冲等高频场景,它开销明显
  • 它适合写多读少、或生产者/消费者数量动态变化的场景,不适合要求强一致 size 或严格 FIFO 顺序校验的业务
  • 如果业务需要阻塞语义(比如取不到就等),别硬套它,应选 LinkedBlockingQueue 等带锁队列

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11297

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8402

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7252

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1204

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

988

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1456

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2969

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20231

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1315

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习