双重检测
class Singleton{
private volatile static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if(instance==null) {
synchronized (Singleton.class) {
if(instance==null)
instance = new Singleton();
}
}
return instance;
}
}
双重检测是为了提高效率,如果不同步可能产生多个对象,如果将整个函数同步了那么每次都要同步,其实读是不用同步的,这样写只有在第一需要同步,而在以前这样写也会不对,因为可能重排序是使instance先获得地址,而实例却还没写入地址。后来volatile不准重排序就解决了这个问题。
基本定义
对volatile变量的写会立即从线程的工作内存写入到主存中,并且会使其他线程工作内存(或者是高速缓存?)中的变量失效,迫使她重读。而普通变量不会这样。
volatile变量不是原子性的这种x++其实包含了好几个操作。
volatile使编译器不会重排。
而声明变量是volatile的,JVM保证了每次读变量都从内存中读,跳过CPU cache这一步。
今天又看到这么依旧 那么问题来了 volatile到底是使缓存失效,还是直接读的内存。