什么是单例模式

单例模式确保一个类只有一个实例,并提供一个全局访问点,实现单例模式的方法是私有化构造函数,通过getInstance()方法实例化对象,并返回这个实例

保证在JVM中只有一个实例 幂等
JVM中如何保证实例的幂等问题 保证唯一性

饿汉、懒汉 双重检验

单例模式优缺点

1、单例类只有一个实例
2、共享资源,全局使用
3、节省创建时间,提高性能

缺点:可能存在线程不安全的问题 解决线程安全问题

如何破解单例

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Constructor<SingletionV5> declaredConstructor = SingletionV5.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        SingletionV5 singletionV5 = declaredConstructor.newInstance();

    }

饿汉式

/**
 * 饿汉式 优点:先天性 线程安全,当类初始化的时候,就会创建对象
 *       缺点:如果项目使用过多的饿汉式,会发生问题。越多启动越慢,存放方法去占用内存比较大
 */
public class SingletionV1 {
    private static  SingletionV1 singletionV1=new SingletionV1();
    //1。单例模式 是否可以让程序员 初始化
    private SingletionV1() {

    }
    public SingletionV1 getInstance(){
        return  singletionV1;
    }
}

懒汉式

public class SingletionV2 {
    //懒汉式  当真正需要的时候才被初始化
    private static  SingletionV2 SingletionV2;

    private SingletionV2() {

    }

    /**
     * 线程不安全,多线程情况下,可能会初始化多次
     * @return
     */
    public static SingletionV2 getInstance(){
        if (SingletionV2 == null) {
            SingletionV2=new SingletionV2();
        }
        return  SingletionV2;
    }
}

双重检验锁

/**
 * 双重检验锁,解决懒汉式 线程安全问题, 
 */
public class SingletionV3 {
    private static  SingletionV3 SingletionV3;
    /**
     * 双重检验锁  读不加锁,写的时候加锁
     */
    public SingletionV3 getSingletionV3(){
        // 当多个线程同时new对象的时候,才会加锁。保证线程安全。
        if (SingletionV3 == null) {
            //只有一个对象 初始化
            synchronized (SingletionV3.class){
                if (SingletionV3 == null) { // 当前线程 已经获取到锁了,
                    SingletionV3 = new SingletionV3();
                }
            }
        }
        return SingletionV3;
    }
    private SingletionV3() {
    }
}

静态内部类

/**
 * 静态内部类
 * 特征:继承懒汉式的优点。同时解决双重检验锁
 */
public class SingletionV5 {
    private  SingletionV5() {
        
    }
    //在 类里面 嵌套一个类
    private static class SingletionV5Utils{
        private static final SingletionV5 singletionV5=new SingletionV5();
    }

    public static SingletionV5 getSingleton(){
        return SingletionV5Utils.singletionV5;
    }
}

枚举

public enum EnumSingleton {
    INSTANCE;

    // 枚举能够绝对有效的防止实例化多次,和防止反射和序列化破解
    public void add() {
        System.out.println("add方法...");
    }
}