本文主要是介绍好未来面试补充,,violate关键字的作用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字。
volatile,从字面上说是易变的、不稳定的,事实上,也确实如此,这个关键字的作用就是告诉编译器,只要是被此关键字修饰的变量都是易变的、不稳定的。那为什么是易变的呢?因为volatile所修饰的变量是直接存在于主内存中的,线程对变量的操作也是直接反映在主内存中,所以说其是易变的。
什么是主内存?为什么是在主内存中?先看看java的内存模型(JMM)中内存与线程的关系。
图片来自《深入理解Java虚拟机》
JMM中的内存分为主内存和工作内存,其中主内存是所有线程共享的,而工作内存是每个线程独立分配的,各个线程的工作内存之间相互独立、互不可见。在线程启动的时候,虚拟机为每个内存分配了一块工作内存,不仅包含了线程内部定义的局部变量,也包含了线程所需要的共享变量的副本,当然这是为了提高执行效率,读副本的比直接读主内存更快。
那么对于volatile修饰的变量(共享变量)来说,在工作内存发生了变化后,必须要马上写到主内存中,而线程读取到是volatile修饰的变量时,必须去主内存中去获取最新的值,而不是读工作内存中主内存的副本,这就有效的保证了线程之间变量的可见性。
volatile特性一:内存可见性,即线程A对volatile变量的修改,其他线程获取的volatile变量都是最新的。
举个栗子:
volatile boolean flag;
...
while(!flag){
doSomeThing();
}
- 1
- 2
- 3
- 4
- 5
检查标记判断退出循环
volatile的例子很难重现,因为只有在对变量读取频率很高的情况下,虚拟机才不会及时写回到主内存,而当频率没有达到虚拟机认为的高频率时,普通变量和volatile是同样的处理逻辑。
volatile特性二:可以禁止指令重排序
至于重排序是啥?我们通过个简单的例子了解下。
public class SimpleHappenBefore {/** 这是一个验证结果的变量 */private static int a=0;/** 这是一个标志位 */private static boolean flag=false;public static void main(String[] args) throws InterruptedException {//由于多线程情况下未必会试出重排序的结论,所以多试一些次for(int i=0;i<1000;i++){ThreadA threadA=new ThreadA();ThreadB threadB=new ThreadB();threadA.start();threadB.start();//这里等待线程结束后,重置共享变量,以使验证结果的工作变得简单些.threadA.join();threadB.join();a=0;flag=false;}}static class ThreadA extends Thread{public void run(){a=1;flag=true;}}static class ThreadB extends Thread{public void run(){if(flag){a=a*1;}if(a==0){System.out.println("ha,a==0");}}}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
这里有两个共享变量a和flag,初始值分别为0和false。在ThreadA中先给a=1,然后flag=true。 如果按照有序的话,那么在ThreadB中如果if(flag)成功的话,则应该a=1,而a=a*1之后a仍然为1,下方的if(a==0)应该永远不会为真,永远不会打印。
但实际情况是,在试验100次的情况下会出现0次或几次的打印结果,而试验1000次结果更明显,有十几次打印。
以上这种现象就是由于指令重排序造成的。
那么什么是指令重排序?–为了尽可能减少内存操作速度远慢于CPU运行速度所带来的CPU空置的影响,虚拟机会按照自己的一些规则将程序编写顺序打乱。
如果变量没有volatile修饰,程序执行的顺序可能会进行重排序。
这篇关于好未来面试补充,,violate关键字的作用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!