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

Java 并发中的原子类

1. 为什么需要原子类

多线程环境下,有个常见问题:

publicclassCounter{privateintcount=0;publicvoidincrement(){count++;}}

count++看似一行代码,实际分三步:

  1. 读取 count 的值
  2. 加 1
  3. 写回 count

多线程下可能发生:

线程A:读取 count=0 线程B:读取 count=0 线程A:count=1,写回 线程B:count=1,写回 // 线程A的结果被覆盖了

最终 count=1,但实际应该等于 2。

2. 解决办法

synchronized 加锁

publicsynchronizedvoidincrement(){count++;}

缺点:性能差,每次只能一个线程进入。

原子类

privateAtomicIntegercount=newAtomicInteger(0);publicvoidincrement(){count.incrementAndGet();}

一行搞定,性能比 synchronized 高很多。

3. 常用原子类

AtomicInteger

AtomicIntegercount=newAtomicInteger(0);// 加1count.incrementAndGet();// ++icount.getAndIncrement();// i++// 减1count.decrementAndGet();// --icount.getAndDecrement();// i--// 加任意值count.addAndGet(5);// 获取值intvalue=count.get();// 设置值count.set(100);// CAS 操作count.compareAndSet(100,200);// 如果当前值是100,则设置为200

AtomicLong

和 AtomicInteger 用法一样,只是类型不同:

AtomicLongcount=newAtomicLong(0);count.incrementAndGet();

AtomicBoolean

AtomicBooleanflag=newAtomicBoolean(false);// 设为 trueflag.set(true);// CAS 操作flag.compareAndSet(false,true);

AtomicReference

用来原子更新对象:

AtomicReference<User>userRef=newAtomicReference<>();Useruser1=newUser("张三",20);Useruser2=newUser("李四",25);userRef.set(user1);userRef.compareAndSet(user1,user2);// 如果当前是 user1,则改为 user2

4. 数组原子类

// 数组中某个元素原子操作AtomicIntegerArrayarr=newAtomicIntegerArray(newint[]{1,2,3});arr.getAndAdd(0,10);// 第一个元素加10intvalue=arr.get(0);// 获取第一个元素

5. 累加器

jdk8 新增的,比 AtomicInteger 性能更高,专门用于累加场景:

LongAddercount=newLongAdder();count.add(1);count.increment();longvalue=count.sum();

内部原理是把一个值拆成多个 Cell,减少竞争。适合高并发场景下的累加。

// AtomicInteger vs LongAdder// 低并发:两者差不多// 高并发:LongAdder 性能更好

6. 实战示例

计数器

publicclassPageViewCounter{privateAtomicIntegercount=newAtomicInteger(0);publicvoidaddView(){count.incrementAndGet();}publicintgetViews(){returncount.get();}}

防止重复提交

publicclassSubmitService{privateAtomicBooleansubmitting=newAtomicBoolean(false);publicvoidsubmit(){// 如果已经在提交中,直接返回if(!submitting.compareAndSet(false,true)){return;}try{// 业务逻辑doSubmit();}finally{submitting.set(false);}}}

配置更新

publicclassConfigHolder{privateAtomicReference<Config>configRef=newAtomicReference<>();publicvoidupdateConfig(ConfignewConfig){configRef.updateAndGet(old->newConfig);}publicConfiggetConfig(){returnconfigRef.get();}}

7. 总结

用途
AtomicInteger整数原子操作
AtomicLong长整数原子操作
AtomicBoolean布尔原子操作
AtomicReference对象引用原子操作
AtomicIntegerArray整数数组原子操作
LongAdder高并发累加,比 AtomicLong 性能更好

什么时候用:

  • 需要保证多线程安全地修改一个值时
  • 简单计数、状态标记等场景
  • 比 synchronized 性能更好
http://www.jsqmd.com/news/754703/

相关文章:

  • 2026年4月目前做得好的包衣烘干一体机直销厂家口碑推荐,蒸汽去皮机/法式薯条加工,包衣烘干一体机实力厂家哪家可靠 - 品牌推荐师
  • C# 13模块化开发实战:3步将遗留控制台项目升级为NuGet可引用模块(附自动化迁移脚本)
  • C++27原子操作性能跃迁指南(LLVM 18+Clang 19实测基准报告):从32ns到8.6ns的确定性优化闭环
  • ARM架构STR指令详解与应用实践
  • 如何用Dell Fans Controller实现戴尔服务器风扇静音控制?5个实用技巧
  • 别再只调波特率了!STM32CubeMX配置RS485半双工通信的完整避坑指南(附收发切换代码)
  • 保姆级教程:LSF集群资源限制(limit)配置详解,从配置文件到实战避坑
  • LFM2-2.6B-GGUF快速上手:WebUI中快捷键与输入法兼容技巧
  • 卫星影像三维重建:NeRF技术实现城市建模革新
  • 汽车ECU诊断服务AOP重构实录:用C# 13拦截器替代PostSharp后,CI构建耗时减少62%,部署包体积压缩83%
  • 收藏!2026 年版:未来 10 年,职业发展潜力最大的领域(小白 程序员必看)
  • PostgreSQL主从切换实战:当主库宕机后,如何5分钟内手动完成故障转移(流复制环境)
  • 自蒸馏策略优化(SDPO)在强化学习中的应用与实践
  • 这里是小通知!
  • Windows Defender Remover终极指南:专业深度解析Windows安全组件管理工具
  • 冒险岛游戏资源终极定制指南:使用Harepacker-resurrected打造个性化游戏体验
  • 开源运维平台OpenClaw-Ops:从GitOps到可观测性的实践指南
  • 终极指南:如何在英雄联盟国服免费解锁所有皮肤
  • Prismer Cloud:为AI Agent构建进化引擎与集体智慧基础设施
  • HCIP-vlan综合实验
  • 自托管AI助手平台c4 GenAI Suite:模块化架构与MCP集成实战
  • 企业级数字化运营平台建设方案研究
  • Matplotlib保存图片总是一片空白?别急,先检查plt.show()和savefig()的顺序
  • PHP开发者的OpenAI API客户端库选择:kousen/OpenAIClient深度解析与实践指南
  • FreeRTOS菜鸟入门(二十)·ARM架构简介
  • Flir Blackfly S多相机同步避坑指南:从SpinView配置到常见故障排查
  • RP2040 pHAT开发板:双模式微控制器与树莓派扩展板
  • YOLOv11户外徒步场景背包目标检测数据集-715张-backpack-1_6
  • 转载--AI Agent 架构设计:人和 Agent 的边界在哪里(OpenClaw、Claude Code、Hermes Agent 对比)
  • AI编程工具包深度解析:Cursor与Claude协同的工程化实践