public class Singleton { private Singleton(){}//私有化构造器 private static Singleton instance = null; //类的内部创建对象 public static Singleton getInstance(){ //暴露公共的get方法 if(instance == null){ instance = new Singleton(); } return instance; } } //饿汉 class Singleton2{ private Singleton2(){} //只实例化一次,线程安全。 但是有些浪费空间 private static Singleton2 instance = new Singleton2(); public static Singleton2 getInstance(){ return instance; } } //双重检测锁 懒汉模式 /* * 可能存在的问题:线程a进行第一次访问,①处为null拿到锁②也为null 执行③ * instance = new Singleton3() 会被编译器编译成JVM指令 * * memory = allocate(); //1.分配内存空间 * ctorInstance(memory); //2.初始化对象 * instance = memory; //3.将instance指向刚分配的地址 * * 可能JVM将指令优化重排为 1 3 2 * * 当a线程执行到3时CPU被b线程拿到,此时b线程①出不为null 直接返回instance * 而此时的instance只有内存地址,并没有初始化完成 * * */ class Singleton3{ private Singleton3(){} private static Singleton3 instance = null; public static Singleton3 getInstance(){ if(instance == null){ //① synchronized (Singleton3.class) { if(instance == null){//② instance = new Singleton3(); //③ } } } return instance; } } //双重检测锁 懒汉模式 volatile class Singleton4{ private Singleton4(){} //volatile 阻止指令重排、禁用线程内存 保证每次都读写主内存的值 private volatile static Singleton4 instance = null; public static Singleton4 getInstance(){ if(instance == null){ synchronized (Singleton4.class) { if(instance == null){ instance = new Singleton4(); //volatile修饰的变量不会指令重排 } } } return instance; } } //双重检测锁 懒汉模式 volatile +优化 /* * volatile 阻止指令重排,读取volatile修饰的变量消耗的性能会比较大 * * 所以创建临时变量,在instance不为null时,直接返回临时变量,不再去访问volatile的变量 提高25%的性能 * */ class Singleton5{ private Singleton5(){} private volatile static Singleton5 instance = null; public static Singleton5 getInstance(){ Singleton5 inst = instance; //创建临时变量 if(instance == null){ synchronized (Singleton5.class) { if(instance == null){ inst = new Singleton5(); instance = inst; } } } return inst; //返回临时变量 } }