5.volatile是什么?怎么保证可见性?

简介: 5.volatile是什么?怎么保证可见性?

volatile是什么?

volatile可参考之前写过的文章:java中volatile关键字

老王:小陈啊,上一章节结束之前让你看一下volatile,现在研究得怎么样了?

小陈:上一章结束之后啊,我回去看了一下资料,大概知道volatile是个啥东西了。

老王:哦,那你来说说。

小陈:volatile是java语言提供的一个关键字,用来修饰变量的,使用volatile修饰的变量可以保证并发安全的可见性和有序性。

小陈:volatile关键字的用法大概是下面这样的:

java

复制代码

volatile int i = 0;
public void add() {
    i++;
}

使用方法就是声明变量之前加一个volatile关键字,然后变量 i 的操作就跟我们平常的操作是一样的。

但是添加的volatile的变量,在编译之后JVM会在操作该变量的前后添加一些指令来保证可见性和有序性,具体添加了啥指令这个到时候还得靠老王你来讲解一下哈,因为我还没了解到那一步,哈哈。

volatile对可见性保证

老王:哈哈,没关系,到时候我再补充一下,你先来先说说volatile怎么保证可见性的?

小陈:结合之前讲的MESI缓存一致性协议,看了一些资料。大概知道volatile在JMM层次和CPU高速缓存层次是怎么确保可见性的了

老王:哦,这么机灵,那你来说说看....

小陈:使用volatile关键字修饰的共享变量,每次线程使用之前都会重新从主内存中重新读取最新的值; 一旦该共享变量的值被修改了,修改它的线程比如立刻将修改后的值强制刷新回主内存

小陈:我画个图来说一下:

image.png

(1)首先看一下上面的图,有工作线程A、工作线程B;假如之前工作线程A、B都是用过这个共享变量 i,工作内存中都有变量副本 i = 0

(2)这个时候工作线程A要执行 i++ 操作,按照volatile关键字的特性每次使用之前必须从主内存重新读取,所以工作线程A重新从主内存读取(执行read、load指令)得到 i = 0没有变化

(3)然后执行use指令将 i = 0 传递给工作线程,执行 i++  操作,得到 i = 1

(4)然后执行assign指令,将 i = 1的结果赋值给工作线程按照volatile的特性一旦共享变量的值被修改了,需要立即强制刷新回主内存。 所以在执行assign赋值更新后的之后,立马执行store、write指令将最新的值传递到主内存,并且赋值给主内存的变量。

(5)此时工作线程B需要用到共享变量 i 了,即使工作内存里面有副本,但是每次还是会重新从主内存中读取最新的值,这个时候读取到 i = 1了

小陈:上面就是我知道的,volatile在java内存模型层次是怎么保证可见性的。

小陈:之前我们了解过MESI一致性怎么实现可见性了,由于java内存模型建立在CPU多级缓存模型之上所以java内存模型底层也是通过MESI一致性的协议去达到可见性的目的,java内存模型会去适配不同操作系统对MESI一致性协议的不同实现方式。

老王:很好啊小陈,非常不错,棒棒的......


小陈:还好啦..,嘿嘿......

小陈:老王啊,我对volatile的了解就到这里了,后面其实我还有挺多疑问的,volatile修饰的变量,怎么让每都让它从主存读取最新数据的?修改了之后立刻刷新会主内存这个是怎么实现的?

还有volatile我看了一些资料说是通过禁止重排序来实现有序性的,那到底是通过什么来禁止重排序的?

老王:其实这个就涉及到一个内存屏障的概念了,其实volatile的可见性和有序性都是通过内存屏障来实现的。

包括你上面说的读取数据的时候强制读取主内存数据,修改数据之后强制刷新到主内存,都是有相对应的内存屏障指令对应的。

还有为了实现有序性而禁止volatile前后相关的指令进行重排序,在JVM乃至操作系统都是有相应的内存屏障指令的。

至于具体什么是内存屏障?有什么作用?我们下面的篇章再慢慢聊,今天就先到这里,我们下一章再见......

小陈:好的,我们下一章见。

相关文章
|
16天前
|
缓存 安全 Java
多线程的三大特性:原子性、可见性和有序性
多线程的三大特性:原子性、可见性和有序性
18 0
|
5月前
|
存储 安全 Java
关于volatile解决内存可见性问题(保证线程安全)
关于volatile解决内存可见性问题(保证线程安全)
|
5月前
|
安全 Java
7.volatile怎么通过内存屏障保证可见性和有序性?
7.volatile怎么通过内存屏障保证可见性和有序性?
30 0
7.volatile怎么通过内存屏障保证可见性和有序性?
|
5月前
|
缓存 Java
13.synchronized总结:怎么保证可见性、有序性、原子性?
13.synchronized总结:怎么保证可见性、有序性、原子性?
42 0
13.synchronized总结:怎么保证可见性、有序性、原子性?
|
5月前
|
缓存 安全 Java
3.线程安全之可见性、有序性、原子性是什么?
3.线程安全之可见性、有序性、原子性是什么?
44 0
3.线程安全之可见性、有序性、原子性是什么?
|
5月前
|
Java
8.volatile为啥不能保证原子性?
8.volatile为啥不能保证原子性?
30 0
8.volatile为啥不能保证原子性?
|
10月前
volatile 的作用是什么?能保证原子性吗?能保证有序性吗?
volatile 的作用是什么?能保证原子性吗?能保证有序性吗?
70 0
|
存储 安全 Java
Volatile能不能保证线程安全?
Volatile能不能保证线程安全?
|
Java
简单说说原子性、可见性、有序性
原子性、可见性、有序性
306 0
|
算法 Java 编译器
线程安全性详解(原子性、可见性、有序性)()2
线程安全性详解(原子性、可见性、有序性)
169 0
线程安全性详解(原子性、可见性、有序性)()2