简介
volatile是Java语言中的一种轻量级的同步机制,它可以确保共享变量的内存可见性,也就是当一个线程修改了共享变量的值时,其他线程能够立即知道这个修改。跟synchronized一样都是同步机制,但是相比之下,synchronized属于重量级锁,volatile属于轻量级锁。
JMM概述
JMM就是Java内存模型(Java Memory Model),是Java虚拟机规范的一种内存模型,屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果。
Java内存模型规定了Java程序的变量(包括实例变量,静态变量,但是不包括局部变量和方法参数)全部存储在主内存中,定义了各种变量(线程的共享变量)的访问规则,以及在JVM中将变量存储到主内存与从主内存读取变量的底层细节。
JMM的规定
- 所有共享变量都存在于主内存(包括实例变量,静态变量,但是不包括局部变量和方法参数),因为局部变量是线程私有,不存在竞争问题。
- 每个线程都有自己的工作内存,所需要的变量是主内存中的副本。
- 线程对变量的读、写操作都只能在工作内存中完成,不能直接参与读写主内存的变量。
- 不同的线程也不能去直接访问不同线程的工作内存的变量,线程间的变量传递需要通过主内存来中转完成。
volatile的特性
1、可见性
volatile可以保证线程的可见性,即当多个线程访问同一个变量的时候,此变量发生改变,其他线程也能实时获得到这个修改的值。
在java中,变量都会被放在推内存(所有线程共享的内存)中,多个线程对共享内存是不可见的,当每个线程去获取这个变量的值时,实际上是copy一份副本在线程自身的工作内存中。
举个例子
我们将main作为主线程,MyThread为子线程。在子线程中定义一个共享变量flag,主线程会去访问这个共享变量。在不加volatile的时候,flag在主线程读到的永远是为false,因为两个线程是不可见的。
public class T2_Volatile01 {
public static void main(String[] args) { // 主线程
MyThread my = new MyThread();
my.start();
while (true) {
if (my.isFlag()) System.out.println("进入等待...");
}
}
}
cl