面试官: 有了解过volatile关键字吗 说说看
前言
目前正在出一个Java多线程专题长期系列教程,从入门到进阶含源码解读, 篇幅会较多, 喜欢的话,给个关注❤️ ~ 本篇内容纯理论一点
概念回顾
首先我们回顾一下之前讲的基本概念:
内存可见性
「内存可见性,指的是线程之间的可见性,当一个线程修改了共享变量时,另一个线程可以读取到这个修改后的值」。
重排序
为优化程序性能,对原有的指令执行顺序进行优化重新排序。重排序可能发生在多个阶段,比如编译重排序、CPU重排序等。
happens-before
遵循happens-before规则,JVM就能保证指令在多线程之间的顺序性符合执行的预期。
volatile
-
保证变量的「内存可见性」 -
禁止volatile变量与普通变量「重排序」
那么这个内存可见性过程是怎么样的呢❓之前也有给大家演示过具体代码,这里直接给大家总结一下:
所谓内存可见性, 当一个线程对volatile修饰的变量进行写操作时,会立即将本地内存中的共享变量刷新到主内存, 同理,当进行读操作时,会立即将本地内存失效,从主内存中读取共享变量的值。
在这一点上,volatile与锁具有相同的内存效果,volatile变量的写和锁的释放具有相同的内存语义,volatile变量的读和锁的获取具有相同的内存语义。
禁止重排又是怎么回事呢❓
在JSR-133之前的旧的Java内存模型中,是允许volatile变量与普通变量重排序的。想想看,如果可重排,会发生什么?
我们假设有两个线程A和B,一个被volatile修饰的变量a,一个未被修饰的普通变量b,看下边代码:
class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
这样在多线程环境下,可以保证其安全性
结束语
本节内容可能不像之前那么好理解,比较抽象,所以本文也有不足的地方,大家自己可以多查查一些资料,综合理解, 不要去背概念。本节我们提到了锁的概念,下一节,带大家深入学习一下Java的synchronized与锁 ~
往期内容推荐
-
-
-
-
-
-
-
-
-
-
我的博客(阅读体验较佳)
-
-
-
-
-
项目源码(源码已更新 欢迎star⭐️)
-
java-thread-all
-
地址: https://github.com/qiuChengleiy/java-thread-all.git
推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)
-
springboot-all
-
地址: https://github.com/qiuChengleiy/springboot-all.git -
-

本篇文章来源于微信公众号: 程序员皮卡秋
微信扫描下方的二维码阅读本文

Comments NOTHING