今天会是有offer的一天么-java中volatile关键字的使用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了今天会是有offer的一天么-java中volatile关键字的使用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2440字,纯文字阅读大概需要4分钟。
内容图文
写在前面
volatile关键字在面试中也算是高频问题了,基本上涉及到并发都会被问到这个问题。今天来简单的总结一下。
先说一下volatile关键字的作用
一. 禁止指令重排
何为禁止指令重排?用一个代码简单解释一下
public class Singleton {
//这里用volatile修饰的目的就是防止指令重排
private static volatile Singleton singleton;
private Singleton(){}
public static Singleton getSingleton(){
if(singleton==null){
synchronized (Singleton.class){
if(singleton==null){
//对于这一行代码,其实是分为三个部分执行的
//首先分配对象的内存空间
//初始化对象
//将对象指向刚分配的内存地址
//如果不用volatile关键字修饰,第二步和第三步可能会调换顺序
//假如有两个线程同时访问,线程A执行完第一步和第三步还未执行第二步,此时线程B认为sigleton已经初始化完毕,就会带来问题。
singleton=new Singleton();
}
}
}
return singleton;
}
}
实现方式
在JVM层面上,volatile内存区的读写都加上了内存屏障,用于实现对内存操作的限制。
二. 保证“共享变量”的可见性
何为可见性,为什么要保证可见性
首先说明一点,对于单核CPU来讲,是不存在可见性问题的,当然目前的计算机一般都是多核CPU,那么这就会带来可见性问题。例如说我们去执行几行java代码,那么最终这些代码是会交给我们的CPU去执行的,而代码中的一些数据是存放在内存中的。而CPU在去操作这些数据的时候,是不会直接操作内存的,因为每个CPU都有一个自己独立的缓存。例如在对数据进行修改时,首先会将数据从内存装载到缓存;接着在缓存中对数据进行修改;最后将修改后的数据刷新到内存中。
所以对于单核CPU是不存在可见性问题的,但如果是多核就会存在问题。例如我们有两个线程A和B去操作同一变量,线程A交给CPU1去执行,线程B交给CPU2去执行;接着CPU1将数据装载到自己的缓存中进行修改,CPU2将数据装载到自己的缓存中进行修改。最后都将修改后的数据刷新到缓存中。这里面就会出现一个问题,因为每个CPU的缓存都是独立的,CPU1是不知道其CPU2是否已经对数据进行了修改,假如说CPU2将变量由10修改为5,但是CPU2这个时候的缓存中仍然保存的是旧的数据,那么最终就会导致结果出现问题。
volatile 关键字保证可见性的实现方式
在对有volatile关键字修饰的变量进行写操作的时候,汇编后的代码会多出一个LOCK前缀指令,那么这个指令在多核CPU下会引发两件事情:
一. 立刻将当前CPU缓存行中的数据写回到系统内存。(强调一点,如果没有volatile关键字进行修饰,CPU在更新完数据以后是不会立刻将更新后的数据写会到内存中)
二. 这个写会内存的操作会导致其他CPU缓存了该内存地址的数据无效。在多核CPU下,每个CPU都会嗅探在总线上传播过来的数据,来检查自己的缓存是否过期,如果发现缓存行对应的内存地址被修改也就是过期了,就会将当前CPU缓存行设置为无效状态,当需要操作这个数据的时候,会重新从内存中把数据读到缓存行中。
最后说一点volatile关键字是不能保证数据的原子性的。
内容总结
以上是互联网集市为您收集整理的今天会是有offer的一天么-java中volatile关键字的使用全部内容,希望文章能够帮你解决今天会是有offer的一天么-java中volatile关键字的使用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。