0

0

Java并发编程中原子类怎么用_无锁操作原理讲解

P粉602998670

P粉602998670

发布时间:2026-01-24 05:03:08

|

123人浏览过

|

来源于php中文网

原创

AtomicInteger等原子类仅在单变量简单读-改-写场景下安全高效,依赖CPU级CAS指令实现无锁原子性,不适用于复合操作,不可替代synchronized。

java并发编程中原子类怎么用_无锁操作原理讲解

AtomicInteger 等原子类不是“线程安全的替代品”,而是特定场景下的无锁优化手段

直接说结论:Java 的 AtomicIntegerAtomicReference 等原子类,**只在单变量读-改-写(read-modify-write)且逻辑简单时才真正安全高效**。它们不是 synchronized 的平替,更不能覆盖复合操作。用错反而掩盖竞态,比加锁还难排查。

compareAndSet 是原子类的核心,不是“自动加锁”而是 CPU 级 CAS 指令

compareAndSet 的行为是:检查当前值是否等于预期值,是则更新为新值并返回 true;否则不修改,返回 false。它依赖底层 CPU 的 CAS(Compare-And-Swap)指令,无需操作系统介入,所以叫“无锁”。但这也意味着——

  • 它不阻塞线程,失败后需由你决定重试(比如用 getAndIncrement 内部的自旋循环)
  • 它只保证一次操作的原子性,if (i.get() 这种判断+更新仍是竞态
  • 在高争用下,自旋可能浪费大量 CPU(尤其多核竞争同一变量时)
int expected;
do {
    expected = counter.get();
} while (!counter.compareAndSet(expected, expected + 1)); // 手动实现 increment

AtomicReference 适合封装不可变状态,但注意 ABA 问题和引用泄漏

AtomicReference 常用于无锁、队列或状态机,比如用一个 volatile Node 记录头节点。但它不解决 ABA 问题:某个值从 A → B → A,compareAndSet 会误认为没变过。JDK 提供了 AtomicStampedReference 用版本号缓解,但代价是额外字段和内存开销。

  • 不要把可变对象塞进 AtomicReference(如 AtomicReference<List>),外部仍可并发修改 List 内容
  • 若用它存 Builder 或临时对象,注意 GC 压力——每次 set 都可能丢弃旧引用,导致短生命周期对象暴增
  • 初始化必须用 new AtomicReference<>(initialValue),空构造器初始值为 null,容易 NPE

性能不是绝对优势,要测真实场景下的吞吐与延迟拐点

原子类快,但快多少取决于争用程度和操作粒度。在低并发(AtomicInteger 通常比 synchronized 快 2–5 倍;但一旦线程数超过核心数,或操作涉及多个字段(比如账户余额+冻结金额同步更新),AtomicLongFieldUpdaterVarHandle 可能比全量锁更复杂,而直接上 ReentrantLock 反而更稳。

AI Web Designer
AI Web Designer

AI网页设计师,快速生成个性化的网站设计

下载

立即学习Java免费学习笔记(深入)”;

  • JDK 9+ 推荐优先用 VarHandle 替代原子类,API 更统一,支持更多内存模型语义
  • DoubleAdder / LongAdder 在高并发计数场景明显优于 AtomicLong,因内部用了分段累加+最终合并
  • 别迷信“无锁=高性能”,LLC(末级缓存)伪共享(false sharing)会让多个原子变量在同一条 cache line 上互相踢出,大幅降速

无锁真正的门槛不在 API 调用,而在对内存模型、CPU 缓存一致性协议(MESI)、以及业务逻辑是否真能拆解成原子步骤的理解。写错的 CAS 循环,比写错的 synchronized 更难定位。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

847

2023.08.22

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

76

2025.10.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

447

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

606

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

766

2023.08.10

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

25

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

44

2026.03.12

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.3万人学习

Java 教程
Java 教程

共578课时 | 81.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号