volatile关键字

volatile:用来修饰变量的一个关键字。

保证了两大并发特性:可见性和有序性。

volatile修饰变量的可见性

申明一点:JVM中的所有变量都是存放在主内存中的,而创建的每个线程都有自己的一个工作内存,工作内存中存放的变量都是从主内存中拷贝过来的副本,该线程每次对变量进行修改或者获取时,都是在自己的工作内存中进行操纵,而不能在主内存中进行相关的操作。同时其他的线程也不能访问该线程对变量进行操作后的值,而是通过主内存进行获取。

普通的变量:变量被线程1修改之后,此时修改过后的变量存储在该线程的工作内存中,而并没有刷新到主内存中。如果此时另外一个线程2来获取该变量的值,获取到的变量的值还是原来主内存的变量的值,但是该变量的值已经被线程1进行了修改,线程2获取到的变量的值就并不是正确的,造成了数据错乱。

volatile修饰的变量:变量被某一个线程修改之后,修改后的变量会被JVM强制刷新在主内存中去,其他线程缓存时发现与主内存中的变量值不一致就会更新自己工作内存中的变量值,所以获取该变量的值是与修改后的值一致,不会发生数据错乱。

volatile修饰的变量禁止重排序:

重排序:指编译器和处理器为了优化程序性能而对指令序列进行重新排序,即就是对某个线程中的代码进行了重新的执行顺序。

单线程下:重排序后对其结果没有影响

多线程下:改变了代码的执行顺序之后会对对其他的线程获取到的值不一致,会导致最后的结果出现错误

实现原理:在汇编层面会在volatile修饰的变量之前加入一个Memor yBarrier(内存屏障)。

第一、在进行指令重排序时,不会把volatile修饰的变量之后的指令排到内存屏障之前,也不会把volatile修饰的变量之前的指令 排到内存屏障之后,也就是说当指令到内存屏障的位置时,前面的所有指令已经执行完毕。

第二、会强制把执行完指令后的变量值刷新到主内存中。

第三、如果执行的是写操作,那么其他CPU的缓存无效,保证了缓存一致性

注:内存屏障是一个CPU指令,它的作用:保证特定操作执行的顺序性 2、保证某些变量的内存可见性 3、缓存一致性

应用场景:大量数据的共享、单例模式下的双重检验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值