1.volatile 双层检查
public class SingleTon{
private SingleTon{}
//volatile 防止指令重排序
private static volatile SingleTon singleTon = null;
private static SingleTon getInstance(){
if(singleTon == null){
//不需要把synchronized加到方法上,因为只有第一次初始化时会出现问题
synchronized(SingleTon.class){
if(singleTon == null){
singleTon = new SingleTon();
}
}
}
return singleTon;
}
}
对象初始化有三个步骤
1.分配内存
2.初始化值
3.将内存指向引用
当出现指令重排序时执行顺序会变成1 3 2
假设有两个线程
线程1拿到锁发生了指令重排序执行了1 3让后停住
线程2过来执行,判断线程是否为空,因为线程1已经执行了3,所以拿到一个非空半初始化的对象
2.静态内部类,只有在使用的时候才会初始化
public class SingleTon{
private SingleTon{}
private static class SingleTonInstance{
private static final SingleTon singleTon = new SingleTon();
}
public static SingleTon getInstance(){
return SingleTonInstance.singleTon;
}
}