- 单例模式分为懒汉式,饿汉式
- 懒汉式是实例对象为空,只有在需要使用实例的时候再去创建,饿汉式是在类加载的时候就直接创建了对象
- 其中懒汉式因为是需要的时候再去创建实例,所以会存在线程安全的问题,因为多个线程同时访问的话会造成单例失效,所以记录一个,双检查的线程安全的懒汉式
public class SingletonCheck {
// 防止指令重排序
private volatile static SingletonCheck instance;
// 1:构造器私有化
private SingletonCheck(){}
// 2.对外提供获取单例的方法
public static SingletonCheck getInstance(){
// 3.第一次检查,多个线程可以同时访问
if (instance==null){
// 4.加锁,每次只有一个线程能访问
synchronized (SingletonCheck.class){
// 5.再检查
if (instance==null){
instance = new SingletonCheck();
}
}
}
return instance;
}
}
- 如果不使用synchronized关键字进行单例模式,可以使用类的加载机制,实现最高效的单例模式,也就是静态内部类的静态成员
public class SingletonCheck2 {
// 1.构造器私有化
private SingletonCheck2(){}
// 2.写静态内部类
private static class LayLoad{
public static final SingletonCheck2 INSTACNE = new SingletonCheck2();
}
// 3.对外提供方法调用
public static SingletonCheck2 getInstance(){
return LayLoad.INSTACNE;
}
}
- 解析:类加载的规范:访问静态字段时,才会初始化静态字段所在的类
在getInstance方法中调用了LayLoad.INSTACNE,此时才会对LayLoad进行类初始化,因为类初始化是线程安全的,只会执行一次,所以无论如何都只会保证new SingletonCheck2();执行一次,所以SingletonCheck2只会有一个实例
网友评论