一,简介
jdk中提供了volatile关键字,用于修饰变量。提供了两层语义:
语义一:保证共享变量内存的可见性(并不能保证操作的原子性)。
语义二:禁用指令的重排序。
二,内存可见性原理分析
在Java内存模型中,内存分为主内存(堆内存)和工作内存(栈内存)两个部分,其中主内存是所有线程所共享的,而工作内存则是每个线程分配一份,各线程的工作内存彼此间独立、互不可见,在线程启动的时候,虚拟机为 每个线程分配一块工作内存,不仅包含了线程内部定义的局部变量,还包含了线程所需要使用的共享变量(非线程内构造的对象)的副本,即为了提高执行效率,读取副本比直接读取主内存更快,栈是连续的小空间、顺序入栈出栈,而堆是不连续的大空间,所以在栈中寻址的速度比堆要快很多)。各工作内存之间数据的交换通过主内存来进行的,如下图: 
共享变量在工作内存中发生变化了之后,必须要写回到主内存中(迟早要写回但并非马上写回),但对于volatile关键字修饰的变量则要求工作内存中发生变化之后,必须马上写回到主内存,而线程每次要使用volatile修饰的共享变量时,都会直接到主内存中获取最新的值(而不是读取工作内存中的副本)。从而实现所有线程对该共享变量变化的可见性。
但volatile仅能保证变量的可见性,并不能保证操作的原子性:

private static volatile StoreKeeper instance = null;
private StoreKeeper(){//对象初始化
}
public static StoreKeeper getInstance(){
if(null == instance){
synchronized (StoreKeeper.class)
{
if(null == instance){
instance = new StoreKeeper();
}
}
}
return instance;
}
2万+

被折叠的 条评论
为什么被折叠?



