volatile 关键字的 用法
volatile关键字
什么是可见性?
可见性是指线程A改变变量的值后,线程B可以马上看到更改后变量的值
volatile的作用
关键字volatile提示线程每次从共享内存中读取数据,而不是从私有内存中读取,这样就保证了同步数据的可见性
关键字volatile适用的场景
当想实现一个线程对一个变量进行修改,希望其他线程可以取到最新的值的时候。就需要对变量使用volatile关键字了
我们举一个例子:
import static java.lang.Thread.sleep;
public class VolatileTest {
public static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程1 开始!");
while(flag){
}
System.out.println("线程1 结束!");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程2 开始!");
flag = false;
System.out.println("flag = " + flag);
}
});
t1.start();
sleep(2000);
t2.start();
}
}
- 运行结果
我们可以看到:程序在一直运行,进入了死循环,那么是什么原因造成出现了死循环呢?
- 我么在启动线程t1之后,变量“public static boolean flag = true;”存在于公共堆栈及线程私有的堆栈中,
t1运行后一直在线程私有堆栈中取得的flag的值是true,而线程2的代码“flag = false;”,修改的是公共堆栈中的
flag,所以t1线程私有堆栈中的flag仍然是true。
解决方法 -添加volatile关键字
修改“public static volatile boolean flag = true;”,我们再次运行程序
volatile是否具有原子性?
关键字volatile最大的缺点是不支持原子性,如果修改实例中的数据,比如i++,这样的操作不是原子操作,分为三步
- 从内存中取i的值
- 计算i的值
- 将i的值存入内存中
如果在第二步计算i的值时,其他线程读取i的值,并对i进行修改,这个时候就会出现脏数据,解决方法是使用synchronized关键字
- 参考资料《Java多线程编程核心技术 第二版》
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤