讲师中心 微信公众号
AI工具推荐 视频效率加速

在Java中如何使用AtomicInteger实现原子操作_Java原子类线程安全解析

千敏姑娘_7925

千敏姑娘_7925

发布时间:2026-01-14 11:52:02

|

864人浏览过

|

来源于php中文网

原创

AtomicInteger 的 ++ 或 += 操作不原子,因会分解为读-算-写三步,即使字段 volatile 也无法保证整体原子性;必须使用 incrementAndGet()、compareAndSet() 等原子方法。

在java中如何使用atomicinteger实现原子操作_java原子类线程安全解析

AtomicInteger 能保证对 int 类型的读-改-写操作是原子的,但前提是所有线程都通过它提供的方法(如 incrementAndGet()、compareAndSet())访问,而不是直接读写其内部值。

为什么不能直接用 ++ 或 += 操作 AtomicInteger

AtomicInteger 本身不是“可变的 int”,它的值存放在一个 volatile int 字段里,但 ++ 这类操作会触发三步:读取当前值 → 计算新值 → 写回。即使字段是 volatile,这三步也不具备原子性。

常见错误现象:
- 多线程下执行 counter.get()++ 或 counter.value++(假设你反射访问了私有字段)→ 结果小于预期
- 编译器或 JVM 可能重排序非同步的普通读写,导致逻辑错乱

正确做法必须使用原子方法:

  • counter.incrementAndGet():先加 1 再返回新值
  • counter.getAndIncrement():先返回旧值再加 1
  • counter.addAndGet(5):加指定值并返回结果

compareAndSet() 是唯一能实现条件更新的入口

这是实现无锁算法(如自旋锁、计数器限流、状态机切换)的核心。它等价于「如果当前值等于预期值,则设为新值,并返回 true;否则返回 false」。

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

使用场景举例:实现一个只初始化一次的懒加载计数器

Java Api Extractor
Java Api Extractor

从 Java 项目中提取 Controller 层接口定义为 JSON 数据。

下载
private static final AtomicInteger initialized = new AtomicInteger(0);
private static volatile SomeResource resource;
<p>public static SomeResource getInstance() {
if (resource == null) {
if (initialized.compareAndSet(0, 1)) {
resource = new SomeResource();
}
}
return resource;
}

注意点:
- compareAndSet() 不阻塞,失败后需自行决定是否重试(比如在 while 循环中)
- 第一个参数是「期望的当前值」,不是旧值快照;多线程下可能已被其他线程改过,所以常配合循环使用
- 它底层依赖 CPU 的 CAS(Compare-And-Swap)指令,在 x86 上对应 cmpxchg,JVM 会自动编译为该指令

AtomicInteger 不是万能的:复合操作仍需同步

如果你需要「先判断再更新」且逻辑不可拆分(例如:只有当计数器小于 100 才加 1),compareAndSet() 单次调用无法完成,因为判断和更新之间存在时间窗口。

典型错误写法:

if (counter.get() < 100) {
    counter.incrementAndGet(); // ❌ 中间可能已被其他线程突破 100
}

可行方案有两种:

  • 用循环 + compareAndSet() 实现乐观锁逻辑
  • 对临界区加 synchronized 或使用 ReentrantLock

前者更轻量但可能自旋耗 CPU;后者更稳但引入锁开销。选哪个取决于冲突频率和延迟敏感度。

性能与兼容性:从 Java 5 到 Java 21 都稳定可用

AtomicInteger 自 Java 5 引入,所有现代 JDK(包括 GraalVM、OpenJDK、Zulu)完全支持,无兼容性问题。它的内存语义基于 JMM(Java Memory Model),保证: - get() 总能看到之前任意线程对同一实例的 set() 或原子更新的结果 - 所有原子方法都有与 volatile 字段相同的 happens-before 保证

性能上,纯 CAS 操作比 synchronized 快 3–10 倍(视竞争程度),但在高争用场景下,频繁失败重试反而不如锁稳定。别盲目替换 synchronized —— 先压测,再决定。

真正容易被忽略的是:AtomicInteger 的 toString()、hashCode()、equals() 都只是基于当前值做快照,不参与原子性保证;序列化时也只保存当前数值,不保留操作历史。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6999

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3345

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4388

2025.08.29

C++中int的含义
C++中int的含义

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

2965

2025.08.29

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

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

814

2025.10.23

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

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

4578

2023.08.10

Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

0

2026.11.02

热门下载

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

精品课程

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

共0课时 | 0人学习

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

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn