java的volatile

在Java中,线程之间对内存写入操作的可见性是一个重要的问题,因为每个线程都有自己的工作内存,并且线程之间共享主内存。当一个线程修改了共享变量的值,其他线程并不一定能立即看到这个修改,这就是所谓的可见性问题。

例如下面的例子:

线程t1修改共享变量flag的值并不能被线程t2获取到,线程t2一直没有终止。

为了解决这个问题,Java提供了volatile关键字和synchronized关键字来确保线程之间对内存写入操作的可见性。

volatile关键字

volatile关键字用于修饰变量 ,它确保了对volatile变量的写操作会立即被其他线程看到。当一个线程修改了一个volatile变量的值,新值会立即被写入主内存,并且其他线程会立即看到这个变化。这是因为volatile变量会禁止指令重排序 ,并且当一个线程读取一个volatile变量时,它会从主内存中读取,而不是从自己的工作内存中读取(当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新回主内存中。当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,重新回到主内存中读取最新共享变量)。

但是,volatile并不能 保证复合操作的原子性 ,例如count++这样的操作实际上包含三个步骤:读取、修改和写入。在多线程环境下,这些步骤可能会被其他线程打断,导致数据不一致。
synchronized关键字

synchronized关键字用于修饰方法或代码块 ,它确保同一时刻只有一个线程可以执行某个代码块或方法,从而实现了线程之间的互斥。当一个线程进入synchronized代码块或方法时,它会获取一个锁,其他尝试进入该代码块或方法的线程会被阻塞,直到锁被释放。这就保证了在同一时刻只有一个线程可以修改共享变量,从而避免了可见性问题。

此外,synchronized还确保了内存可见性,即当一个线程释放锁时,它会将修改后的共享变量的值刷新到主内存中,使得其他线程在获取锁并读取共享变量时,能够看到最新的值。

上述例子修改后:

相关推荐
泡泡以安1 分钟前
【Android逆向工程】第3章:Java 字节码与 Smali 语法基础
android·java·安卓逆向
毕设源码-朱学姐6 小时前
【开题答辩全过程】以 工厂能耗分析平台的设计与实现为例,包含答辩的问题和答案
java·vue.js
Spring AI学习7 小时前
Spring AI深度解析(9/50):可观测性与监控体系实战
java·人工智能·spring
java1234_小锋8 小时前
Spring IoC的实现机制是什么?
java·后端·spring
xqqxqxxq8 小时前
背单词软件技术笔记(V2.0扩展版)
java·笔记·python
消失的旧时光-19439 小时前
深入理解 Java 线程池(二):ThreadPoolExecutor 执行流程 + 运行状态 + ctl 原理全解析
java·开发语言
哈哈老师啊9 小时前
Springboot学生综合测评系统hxtne(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·数据库·spring boot
4311媒体网9 小时前
帝国cms调用文章内容 二开基本操作
java·开发语言·php
zwxu_9 小时前
Nginx NIO对比Java NIO
java·nginx·nio
可观测性用观测云10 小时前
Pyroscope Java 接入最佳实践
java