带着问题阅读
1、为什么需要volatile,volatile能解决什么问题
2、volatile的实现原理是什么
3、什么是happen-before
4、volatile是否能保证线程安全
Java内存模型JMM
介绍volatile
之前,首先对Java内存模型进行说明。在C\C++
等语言中,内存管理直接使用物理硬件和操作系统的内存模型,也因此会导致程序无法在不同平台上完全兼容。《Java虚拟机规范》中试图定义Java内存模型(Java Memeroy Model)来屏蔽硬件和操作系统之间的内存访问差异,以达到Java程序的跨平台兼容性。
定义Java内存模型并非易事,模型必须定义严谨,不能让内存访问产生歧义;也必须足够宽松,便于虚拟机有足够的灵活度去利用硬件的特性来提升内存操作速度。经过长时间验证、修补,直到Jdk 5,Java内存模型才成熟起来。
Java内存模型规定所有变量都存储在主内存中(虚拟内存,非物理内存),每条线程都有自己的工作内存,工作内存中拷贝了线程所需变量的副本。线程对所有变量的操作都作用在工作内存的副本上,不能直接操作主内存。不同线程之间的工作内存互相隔离,无法直接访问其他工作内存中的变量。
volatile作用介绍
volatile
是Java提供的最轻量级的同步操作,用于保障可见性和有序性。
可见性
在JMM的介绍中可知,每个Java线程都拥有自己的工作内存,如果两个线程共享同一个变量, 那么每个线程都在自己的工作内存中拷贝了一份该变量。当A线程对变量做出修改后,B线程对变量的修改是不能立即可见的,只有当A线程将变量刷入主内存,并在B线程重新加载主内存变量时,B线程才能得到A线程修改的值。
变量添加volatile
后,即可让修改立即同步到主存中,并要求在使用前立即从主内存重新读取,以保证变量的可见性。
synchronized
释放锁后,同步块的修改都会同步到主存,因此synchronized
也可保证可见性。
有序性
Java程序中天然的有序性可以总结为一句话:如果在本线程内观察,所有操作都是有序的;如果在一个线程中观察另一个线程,所有的操作都是无序的。前半句是指"线程内似表现为串行的寓意",后半句是指"指令重排"和"工作内存与主内存同步延迟"现象。
public class Singleton {
private static volatile instance;
private Singleton() {}
public stativ Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance