变量副本volatile关键字和synchronized同步代码块

文章详细解释了volatile关键字在多线程环境中的作用,它确保了变量在堆内存中的更新能被其他线程看到,但无法保证原子性。同时,通过示例说明了一个无volatile修饰的代码可能导致死循环的问题,以及volatile无法解决的原子性问题。synchronized同步代码块则可以解决这个问题,保证数据操作的原子性和线程安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.volatile

volatile修饰的成员变量,强制要求当前线程同步堆内存里的对应成员变量;堆内存数据所有线程共享,每个线程都有自己独立的线程栈(栈内存);堆内存的成员变量的值会同步给进来的各个线程栈,其中一个线程如果需要修改堆内存中的成员变量,首先修改栈内存中的成员变量又称变量副本,然后同步到堆内存里对应成员变量,由于线程栈都是相互独立的,堆内存的对应已经修改成员变量未及时同步其他线程栈,导致其他线程未获取最新数据,volatile关键字会强制当前线程的线程栈里的变量副本同步堆内存里对应的成员变量,保证数据同步
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、无volatile关键字修饰代码demo

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
代码demo程序进入t1线程里while死循环;
原因:Money.money是t1线程和t2线程的共享数据,t1线程最先开始运行时满足while条件会进入循环,当t2线程开启时已经修改了共享数据,但是t1线程栈中的while条件变量副本还是旧数据并且未同步最新共享数据导致t1线程while条件一直满足程序无法结束,进入死循环

二、volatile关键字修饰代码demo

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

代码demo里t1线程已经跳出while死循环;
原因:Money.money是t1线程和t2线程的共享数据,使用了volatile关键字修饰成员变量,强制当前线程执行任务时,把线程栈里的变量副本同步共享数据(堆内存)最新值,才能继续执行线程任务;最后t1线程当while循环不满足条件跳出死循环,执行循环外面代码,线程任务结束,程序结束

三、volatile关键字不能保证数据的原子性

多线程环境中的线程栈(栈内存)变量副本无法及时同步到共享数据(堆内存)里,导致无法保证成员变量数据值的原子性;
原因:此时当前线程只修改线程栈中的变量副本未及时同步至共享数据(堆内存),就已经失去CPU执行权;另一个线程获取到CPU执行权,获取共享数据时还是第一个线程未及时同步旧的共享数据
在这里插入图片描述

内存模型在这里插入图片描述

volatile代码demo

在这里插入图片描述在这里插入图片描述在这里插入图片描述
以上demo中一个线程执行打印100次,for循环100次创建100个线程,所以最终结果是总共打印10000次;但最终结果是9997次
原因:多线程环境中,每个线程获取CPU执行权都是随机的,即使共享数据count成员变量(atom线程任务对象只实例化了一次,后面代码才开始多线程执行,因此成员变量count是后面多线程执行任务的共享数据)加了volatile关键字可以同步共享数据中的最新值,但其他线程栈中已经修改的变量副本还没同步到共享数据时,已经失去了CPU的执行权,获取CPU执行权的线程同步的共享数据还是旧的,导致最终结果错误
解决办法:共享数据代码加锁,synchronized同步代码块可以确保当前线程任务执行完成才会释放锁,其他线程即使获取了CPU执行权却没有获取锁对象也只能在外面等待
备注:锁和CPU执行权可以确保当前线程完成线程任务并且不被其他线程干扰;锁:不被其他线程干扰,CPU执行权:执行线程任务

四、synchronized同步代码块解决volatile关键字无法实现原子性问题在这里插入图片描述在这里插入图片描述在这里插入图片描述

2.synchronized同步代码块

synchronized作用和volatile关键字一样保证副本变量和堆内存成员变量同步
在这里插入图片描述

synchronized同步代码块Demo

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

臻实

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值