1.聊volatile关键字之前得先补充一些基本概念–JMM(java内存模型)
JMM,一种抽象的概念,Java并发采用它作为共享内存模型:定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。JVM是整个计算机虚拟模型,所以JMM是隶属于JVM。
由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方成为栈空间),工作内存是每个线程的私有数据区域,而Java内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝到自己的工作空间,然后对变量进行操作,操作完成再将变量写回主内存。糙一点的说主内存就是内存条,而工作内存,它并不真实存在。它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。
然后JMM也带来一些问题:
1,可见性问题
2,原子性问题
3,有序性问题
而Volatile关键字的就是Java虚拟机为了解决上面的问题,提供的一种轻量级的同步机制。
更多JMM相关可以点击JMM(Java内存模型Java Memory Model)是什么?
2.Volatile关键字
为什么说Volatile关键字是Java虚拟机提供的轻量级的同步机制。
原因就是Volatile关键字可以保证可见性,可以禁止指令重排序,保证有序性,但却不能保证原子性。
为什么这么说,我们一个一个来看。
2.1 可见性
通过JMM的介绍,我们知道
各个线程对主内存中共享变量的操作都是各个线程各自拷贝到自己的工作内存操作后再写回主内存中的.
这就可能存在一个线程AAA修改了共享变量X的值还未写回主内存中时 ,另外一个线程BBB又对内存中的一个共享变量X进行操作,但此时A线程工作内存中的共享比那里X对线程B来说并不不可见.这种工作内存与主内存同步延迟现象就造成了可见性问题.
我们来写个测试案例
package com.test.volatileDome;
import java.util.concurrent.TimeUnit;
/**
* 1.验证volstile可见性
* 1.1 假如int num = 0;num变量之前没有volatile关键字修饰
*
* @author wangjie
* @version V1.0
* @date 2019/12/14
*/
public class VolatileDemo {
public static void main(String[] args) {
MyData myData = new MyData();
//第一个线程
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t c