news 2026/5/12 0:11:54

Java中为什么volatile不能解决多写问题?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java中为什么volatile不能解决多写问题?

上述规约是一个关于Java并发编程的重要问题。本篇博文我来详细解释一下:

1.volatile的内存可见性

volatile的作用:

  • 保证可见性:当一个线程修改了volatile变量的值,新值会立即刷新到主内存,其他线程读取时会从主内存重新获取最新值
  • 禁止指令重排序:防止JVM的指令重排序优化

示例:

publicclassVolatileExample{privatevolatilebooleanflag=false;publicvoidwriter(){flag=true;// 写操作}publicvoidreader(){if(flag){// 读操作// 一定能看到最新值}}}

2.为什么volatile不能解决多写问题

publicclassCounter{privatevolatileintcount=0;// 多线程调用会有问题publicvoidincrement(){count++;// 不是原子操作:读→改→写}}

问题分析

线程A:读取count=0 线程B:读取count=0 线程A:count+1=1,写回 线程B:count+1=1,写回 // 结果应该是2,实际是1

3.解决方案对比

方案1:AtomicInteger

importjava.util.concurrent.atomic.AtomicInteger;publicclassAtomicExample{privateAtomicIntegercount=newAtomicInteger(0);publicvoidincrement(){count.incrementAndGet();// 原子操作}publicintget(){returncount.get();}}

原理:基于CAS(Compare And Swap)

publicfinalintincrementAndGet(){returnunsafe.getAndAddInt(this,valueOffset,1)+1;}// 实际是自旋CAS操作

方案2:LongAdder(JDK8+推荐)

importjava.util.concurrent.atomic.LongAdder;publicclassLongAdderExample{privateLongAddercount=newLongAdder();publicvoidincrement(){count.increment();// 性能更好}publiclongsum(){returncount.sum();}}

4.性能对比分析

特性AtomicLongLongAdder
原理CAS自旋分段CAS
高并发写性能一般优秀
读性能O(1)O(N)需要合并
内存占用较高
适用场景读写均衡写多读少

5.完整示例

importjava.util.concurrent.atomic.AtomicInteger;importjava.util.concurrent.atomic.LongAdder;importjava.util.concurrent.CountDownLatch;publicclassCounterComparison{// 方案1:volatile(不安全)privatevolatileintvolatileCount=0;// 方案2:AtomicIntegerprivateAtomicIntegeratomicCount=newAtomicInteger(0);// 方案3:LongAdder(JDK8+推荐)privateLongAdderadderCount=newLongAdder();publicvoidtestVolatile()throwsInterruptedException{CountDownLatchlatch=newCountDownLatch(100);for(inti=0;i<100;i++){newThread(()->{for(intj=0;j<1000;j++){volatileCount++;// 线程不安全}latch.countDown();}).start();}latch.await();System.out.println("Volatile结果(可能不正确): "+volatileCount);}publicvoidtestAtomic()throwsInterruptedException{CountDownLatchlatch=newCountDownLatch(100);for(inti=0;i<100;i++){newThread(()->{for(intj=0;j<1000;j++){atomicCount.incrementAndGet();}latch.countDown();}).start();}latch.await();System.out.println("AtomicInteger结果: "+atomicCount.get());}publicvoidtestLongAdder()throwsInterruptedException{CountDownLatchlatch=newCountDownLatch(100);for(inti=0;i<100;i++){newThread(()->{for(intj=0;j<1000;j++){adderCount.increment();}latch.countDown();}).start();}latch.await();System.out.println("LongAdder结果: "+adderCount.sum());}publicstaticvoidmain(String[]args)throwsInterruptedException{CounterComparisontest=newCounterComparison();test.testAtomic();test.testLongAdder();test.testVolatile();}}

6.使用建议

  1. 单写多读:使用volatile
  2. 低竞争环境:使用AtomicInteger/AtomicLong
  3. 高并发写场景:使用LongAdder(JDK8+)
  4. 精确统计场景:使用Atomic系列(LongAdder的sum()可能不是实时精确值)

总结

  • volatile只解决可见性问题,不解决原子性问题
  • 对于count++这类复合操作,必须使用原子类
  • 在JDK8+的高并发写场景下,LongAdder性能通常优于AtomicLong
  • 选择哪个工具取决于具体的读写比例和并发程度
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 18:44:57

【无标题】计算机Java毕设实战-基于SpringBoot的梦想校园快递的设计与实现快递收发 - 智能管理 - 便捷取件【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/5/10 4:24:47

YOLO训练任务取消功能?释放被占用的GPU资源

YOLO训练任务取消功能&#xff1f;释放被占用的GPU资源 在深度学习实验室或AI工程团队中&#xff0c;你是否曾遇到这样的场景&#xff1a;刚刚中断了一个不满意的YOLO训练实验&#xff0c;准备重新启动新配置的任务时&#xff0c;系统却报出“CUDA out of memory”错误&#xf…

作者头像 李华
网站建设 2026/5/10 12:23:48

YOLO目标检测支持历史版本回滚?GPU模型快照

YOLO目标检测支持历史版本回滚&#xff1f;GPU模型快照 在智能制造车间的视觉质检线上&#xff0c;一台搭载YOLOv10的GPU服务器突然开始频繁漏检微小缺陷。运维人员紧急排查后发现&#xff0c;并非硬件故障&#xff0c;而是新部署的模型版本在低光照场景下NMS阈值过于激进所致。…

作者头像 李华
网站建设 2026/5/10 11:53:21

Java毕设选题推荐:基于SpringBoot的梦想校园快递的设计与实现基于SpringBoot的校园快递管理平台 【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/5/10 9:35:43

YOLO目标检测支持Tag过滤?GPU后处理加速

YOLO目标检测支持Tag过滤&#xff1f;GPU后处理加速 在工业质检线上&#xff0c;一台搭载YOLO模型的视觉系统正高速运转——每秒处理30帧1080p图像&#xff0c;实时识别出“划痕”、“缺件”、“异物”等缺陷。但产线切换时&#xff0c;工程师却无需重新训练模型或重启服务&…

作者头像 李华
网站建设 2026/5/10 10:29:52

YOLO模型推理自动扩缩容?根据QPS动态调整GPU数量

YOLO模型推理自动扩缩容&#xff1f;根据QPS动态调整GPU数量 在智能制造工厂的视觉质检线上&#xff0c;一台工业相机每秒拍摄50帧图像&#xff0c;系统必须在200毫秒内完成缺陷检测并触发分拣动作。而到了深夜&#xff0c;产线停机&#xff0c;请求几乎归零——如果此时仍让昂…

作者头像 李华