public class Singleton{
//volatile关键字,是为了禁止指令重排
//singleton = new Singleton;分为三步
//1.为 singleton 分配内存空间
//2.初始化 singleton
//3.将 singleton 指向分配的内存空间
//第2步和第3步交换的话可能会A线程没有被初始化但指向内存地址,
//确实不为null,B线程拿到单例对象是没有初始化的对象
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getInsatance(){
// 增加效率,直接在方法上加锁,就算线程得到有了单例对象也会阻塞别的线程。
//如果单例对象存在,直接返回不用加锁。
if(singleton == null){
sychronized(Singleton.class){
//如果没有第二个if的话,在当前A线程获得锁的线程后可能有其他如B线程也
//在等待进入这个Class锁,A线程获取锁后创建实例,然后释放锁,之后等待
//池中的B线程获得锁,然后就会创建两个对象
if(singleton == null){
singleton = new Singleton;
}
}
}
return singleton;
}
}
//反射会破坏双重校验锁的单例模式,枚举不会(绝对安全)
//反射的setAccessible(true) 暴力反射,可以访问类中的私有属性、方法,从而破坏反射
enum Singleton{
INSTANCE;
public void method(){
//方法
}
}