public class Singleton {
// 懒汉单列模式 volatile 紧张指令重排 多线程可见性(双重检测锁)
private static volatile Singleton singleton;
public Singleton(){}
public static Singleton getInsatace(){
if (singleton==null){ //一重检测 提高多线程下的效率
synchronized (Singleton.class){
if (singleton==null){ // 二重检测
singleton = new Singleton(); //实例化对象
// 实际上创建对象过程中存在三个过程,1.在堆空间开辟空间 2.属性的初始化 3.指向该对象的引用
// 正常cpu执行指令的顺序伪1->2->3没有任何问题
// 但是由于cpu的执行速度是远远大于内存的,指令执行过程中可能出现小部分的延迟
// 于是有可能就发生了1->3->2,属性还没有初始化,对象就指向了引用,引起程序的错误
// volatile关键字就解决了这一问题
}
}
}
return singleton;
}
public static void main(String[] args) {
Singleton i1 = Singleton.getInsatace();
Singleton i2 = Singleton.getInsatace();
System.out.println(i1);
System.out.println(i2);
}
输出一下,javac javap -verbose 查看字节码发现
在两次实例化的过程中,只是new了一次对象的。