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; //返回临时变量
}
}