volatile
1.可见性
 原理:X86处理器下:带volatie的变量 翻译成汇编码是:lock addl.. 意思是在寄存器上进行一个空操作  实现可见性的关键是lock前缀!在多核处理器下lock前缀会做两件事  1.把更新的值推送到主存  lock信号保证在处理期间 锁定这块内存的缓存行 并且写回主存 然后使用缓存一致性协议来保证修改的 原子性 缓存一致性协议会阻止同时修改两个以上的缓存行  2.致其他缓存了该变量的缓存行无效  在缓存一致性协议的下 其他处理器会通过cpu的嗅探技术 查看自己的内存的缓存行的数据是否被修改  如果是则致缓存行无效
2.有序性(防止重排序)
 ·为什么出现指令重排序?-为了提高性能  ·重排的分类:  1.编译器:在不改变单线程程序语义情况下 可以重排序  对于编译器重排JMM的编译器重排规则会禁止某些重排序  2.处理器:数据间不存在依赖性则可以重排序  对于处理器重排 通过加入内存屏障来实现重排序  内存屏障:  Store Store Barriers:写-写不能重排序  Store Load Barriers:写-读不能重排序  Load Load Barriers:读-读不能重排序  Load Store Barriers:读-写不能重排序
 ·happens-before规则  ·线程内的所以操作都happens-before后续操作  ·锁的释放happens-before 随后对这个对象的加锁  ·volatile变量的写 happens-before 在volatile 的读  ·A happens-before B — B happens-before C –> A happens-before C  ·as-if-serial原则:  不管怎么重排都不会对有数据依赖的操作重新排序
 happens-before和as-if-serial本质是一回事  as-if-serial:保证单线程内程序的结果不变 happens-before:保证正确的同步的多线程程序执行结果不变  as-if-serial:单线程下程序看似是顺序执行的 happens-before:正确同步的多线程下程序看似是顺序执行的
 volatile写:加Store Store Barriers 和Store Load Barriers:写-读不能重排序  volatile读:加Load Load Barriers 和Load Store Barriers:写-读不能重排序
 应用:单例模式下的DCL为什么用volatile关键字?  原因:  1.创建对象分三步:  开辟内存空间 赋默认值  调用构造 函数赋初始值  栈中的变量的引用指向堆中的地址  2.其中第二步和第三步在多线程的情况下 可能重排序 导致得到一个未初始化完全的对象  3.加了volatile关键字 会在 new instance 前加 Store Store屏障 在 其后加Store Load屏障  保证volatile写 完后才能读
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//DCL单例
public class sigeton{
    private static volatile sigeton sgt;
    private sigeton(){};
    public sigeton getInstance(){
    	if(sgt==null){
           synchronized(this){
               if(sgt==null){
            		sgt = new sigeton();
        	}
           } 
        }
        return sgt;
    }
    
}								
3.原子性:
 只能保证单一变量的原子性
