『QQ:1353814576』

软件开发设计模式之《精讲设计模式【单例模式】》


什么是单例模式!

单例模式确保一个类只有一个实例,并提供一个全局访问点,实现单例模式的方法是私有化构造函数,通过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方法...");
    }
}