设计模式之单例模式

单例模式

饿汉式

缺点:不管使用与否,类装载时就完成实例化
优点: 实现简单

package com.example.designer.singleton;

/**
 * @version 1.0
 * @create 2022/10/1 00:08
 * @description 单例设计模式之饿汉式
 *
 * 类加载到内存时,就会实例化一个单例,JVM保证了线程安全。
 * 实现简单,推荐使用
 * 唯一的缺点:不管使用与否,类装载时就完成实例化
 *
 */
public class Mgr01 {
    /**
     * 类加载的时候初始化一个实例,放在内存中
     */
    private static final Mgr01 INSTANCE=new Mgr01();

    /**
     * 私有化空参构造方法,使其无法创建对象
     */
    private Mgr01(){}

    /**
     * 获取该实例的唯一途径
     * @return
     */
    public static Mgr01 getInstance(){
        return INSTANCE;
    }

    /**
     * 校验获取到的实例对象就是一个对象。
     * @param args
     */
    public static void main(String[] args) {
        Mgr01 instance1 = Mgr01.getInstance();
        Mgr01 instance2 = Mgr01.getInstance();

        // 返回结果为true
        System.out.println(instance1==instance2);
    }
}

静态代码块实现方式

package com.example.designer.singleton;

/**
 * @version 1.0
 * @create 2022/10/1 00:08
 * @description 单例设计模式之饿汉式
 *
 * 类加载到内存时,就会实例化一个单例,JVM保证了线程安全。
 * 实现简单,推荐使用
 * 唯一的缺点:不管使用与否,类装载时就完成实例化
 *
 */
public class Mgr02 {
    /**
     * 类加载的时候初始化一个实例,放在内存中
     */
    private static final Mgr02 INSTANCE;

    static {
        INSTANCE=new Mgr02();
    }

    /**
     * 私有化空参构造方法,使其无法创建对象
     */
    private Mgr02(){}

    /**
     * 获取该实例的唯一途径
     * @return
     */
    public static Mgr02 getInstance(){
        return INSTANCE;
    }

    /**
     * 校验获取到的实例对象就是一个对象。
     * @param args
     */
    public static void main(String[] args) {
        Mgr02 instance1 = Mgr02.getInstance();
        Mgr02 instance2 = Mgr02.getInstance();

        // 返回结果为true
        System.out.println(instance1==instance2);
    }


}

懒汉式

package com.example.designer.singleton;

/**
 * @version 1.0
 * @create 2022/10/1 00:08
 * @description 单例设计模式之懒汉式
 * <p>
 *     虽然达到了按需使用目的,但是带来了线程不安全
 */
public class Mgr03 {
    /**
     * 类加载的时候初始化一个实例,放在内存中
     */
    private static Mgr03 INSTANCE;

    /**
     * 私有化空参构造方法,使其无法创建对象
     */
    private Mgr03() {
    }

    /**
     * 获取该实例的唯一途径
     *
     * @return
     */
    public static Mgr03 getInstance() {
        if (null == INSTANCE) {
            try {
                Thread.sleep(1);
            }catch (Exception e){

            }
            return new Mgr03();
        }
        return INSTANCE;
    }

    /**
     * 校验获取到的实例对象就是一个对象。
     *
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()-> {
                System.out.println(Mgr03.getInstance().hashCode());
            }).start();
        }
    }
}

添加锁

package com.example.designer.singleton;

/**
 * @version 1.0
 * @create 2022/10/1 00:08
 * @description 单例设计模式之懒汉式
 * <p>
 *     虽然达到了按需使用目的,但是带来了线程不安全
 *     可以通过添加synchronized解决,但是也带来了效率下降
 */
public class Mgr04 {
    /**
     * 类加载的时候初始化一个实例,放在内存中
     */
    private static Mgr04 INSTANCE;

    /**
     * 私有化空参构造方法,使其无法创建对象
     */
    private Mgr04() {
    }

    /**
     * 获取该实例的唯一途径
     * static 方法使用的锁定的是当前对象的class对象。
     *
     * @return
     */
    public static synchronized Mgr04 getInstance() {
        if (null == INSTANCE) {
            try {
                Thread.sleep(1);
            }catch (Exception e){
                e.printStackTrace();
            }
            return new Mgr04();
        }
        return INSTANCE;
    }

    /**
     * 校验获取到的实例对象就是一个对象。
     *
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()-> {
                System.out.println(Mgr04.getInstance().hashCode());
            }).start();
        }
    }
}

在有需要的地方添加锁,提高性能

package com.example.designer.singleton;

/**
 * @version 1.0
 * @create 2022/10/1 00:08
 * @description 单例设计模式之懒汉式
 * <p>
 * 虽然达到了按需使用目的,但是带来了线程不安全
 * 可以通过添加synchronized解决,但是也带来了效率下降
 */
public class Mgr05 {
    /**
     * 类加载的时候初始化一个实例,放在内存中
     */
    private static Mgr05 INSTANCE;

    /**
     * 私有化空参构造方法,使其无法创建对象
     */
    private Mgr05() {
    }

    /**
     * 获取该实例的唯一途径
     * static 方法使用的锁定的是当前对象的class对象。
     *
     * @return
     */
    public static Mgr05 getInstance() {
        if (null == INSTANCE) {
            synchronized (Mgr05.class) {
                try {
                    Thread.sleep(1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return new Mgr05();
        }
        return INSTANCE;
    }

    /**
     * 校验获取到的实例对象就是一个对象。
     *
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr05.getInstance().hashCode());
            }).start();
        }
    }


}

双重判断添加锁(Double check lock. DCL)

package com.example.designer.singleton;

/**
 * @version 1.0
 * @create 2022/10/1 00:08
 * @description 单例设计模式之懒汉式
 * <p>
 * 虽然达到了按需使用目的,但是带来了线程不安全
 * 可以通过添加synchronized解决,但是也带来了效率下降
 */
public class Mgr06 {
    /**
     * 类加载的时候初始化一个实例,放在内存中
     */
    private static volatile Mgr06 INSTANCE;

    /**
     * 私有化空参构造方法,使其无法创建对象
     */
    private Mgr06() {
    }

    /**
     * 获取该实例的唯一途径
     * static 方法使用的锁定的是当前对象的class对象。
     *
     * @return
     */
    public static Mgr06 getInstance() {
        if (null == INSTANCE) {
            synchronized (Mgr06.class) {
                if (null == INSTANCE) {
                    try {
                        Thread.sleep(1);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return new Mgr06();
        }
        return INSTANCE;
    }

    /**
     * 校验获取到的实例对象就是一个对象。
     *
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr06.getInstance().hashCode());
            }).start();
        }
    }


}

静态内部类

package com.example.designer.singleton;

/**
 * @version 1.0
 * @create 2022/10/1 00:08
 * @description 单例设计模式之静态内部类
 * <p>
 *     jvm保证单例
 *     加载外部类时不会加载内部类,这样可以实现懒加载。
 */
public class Mgr07 {

    /**
     * 私有化空参构造方法,使其无法创建对象
     */
    private Mgr07() {
    }

    private static class Mgr07Holder{
        private final static Mgr07 INSTANCE=new Mgr07();
    }

    /**
     * 获取该实例的唯一途径
     * static 方法使用的锁定的是当前对象的class对象。
     *
     * @return
     */
    public static Mgr07 getInstance() {
        return Mgr07Holder.INSTANCE;
    }

    /**
     * 校验获取到的实例对象就是一个对象。
     *
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr07.getInstance().hashCode());
            }).start();
        }
    }


}

枚举

package com.example.designer.singleton;

/**
 * @version 1.0
 * @create 2022/10/1 00:08
 * @description 单例设计模式之枚举
 * <p>
 *     这种是最完美的,还可以防止反序列化
 *
 *     枚举没有构造方法。不可以进行反序列化。
 */
public enum Mgr08 {

    INSTANCE;

    /**
     * 校验获取到的实例对象就是一个对象。
     *
     * @param args
     */
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr08.INSTANCE.hashCode());
            }).start();
        }
    }


}

posted @ 2022-10-01 01:17  King-DA  阅读(27)  评论(0)    收藏  举报