• 设计模式1,单例模式


    类的加载顺序

    • 先执行父类的静态代码块和静态变量初始化,静态代码块和静态变量的执行顺序跟代码中出现的顺序有关。
    • 执行子类的静态代码块和静态变量初始化。
    • 执行父类的实例变量初始化
    • 执行父类的构造函数
    • 执行子类的实例变量初始化
    • 执行子类的构造函数
    单例模式:饿汉式
    /**
     * 单例模式:饿汉式
     *          类加载的时候就完成了实例化
     *      优点:没有线程的安全的问题
     *      缺点:类的实例没有使用的时候就会创建,占用内存
     */
    public class SingleModel1 {
        private SingleModel1() {}
        private final static SingleModel1 INSTANCE = new SingleModel1();
        public static SingleModel1 getInstance() {
            return INSTANCE;
        }
    }
    单例模式:懒汉式1
    /**
     * 单例模式:懒汉式加载
     * 获取实例的时候才会创建对象
     * 优点:解决了对象过早的实例化问题,避免内存浪费
     * 缺点:每次获取实例化的时候因为synchronized产生性能问题
     */
    public class SingleModel2 {
    
        //volatile关键字:保证内存的可见性;避免了指令重排问题,造成实例化未结束的时候,其他线程调用getInstance方法造成的实例的INSTANCE是不完全的,从而造成空指针异常
        private volatile static SingleModel2 INSTANCE = null;
    
        private SingleModel2() {
        }
    
        public synchronized SingleModel2 getInstance() {
            if (INSTANCE == null) {
                INSTANCE = new SingleModel2();
            }
            return SingleModel2.INSTANCE;
        }
    
    }
    单例模式:懒汉式2
    /**
     * 单例模式:懒汉式加载
    * 双重检查懒汉式
    */ public class SingleModel3 { private static volatile SingleModel3 INSTANCE = null; private SingleModel3() { } public static SingleModel3 getInstance() { if (SingleModel3.INSTANCE == null) { synchronized (SingleModel3.class) { //锁的位置不同,减少性能的浪费 INSTANCE = new SingleModel3(); } } return INSTANCE; } }

    静态内部类 (推荐)

    /**
     * 静态内部类模式
     */
    public class SingleModel4 {
    
        private static class InstanceHolder {
            private final static SingleModel4 singleModel4 = new SingleModel4();
        }
    
        public SingleModel4 getInstance() {
            return InstanceHolder.singleModel4;
        }
    
    }

    枚举方式(推荐)

    /**
     * 枚举方式
     */
    public class SingleModel5 {
        private SingleModel5() {
        }
    
        public enum InstanceEnum {
            INSTANCE;
            private final SingleModel5 instance;
    
            InstanceEnum() {
                instance = new SingleModel5();
            }
        }
    
        public SingleModel5 getInstance() {
            return InstanceEnum.INSTANCE.instance;
        }
    }
     
    举例:
      
    单例的线程池

    /**
     * @Auther: ZhangSuchao
     * @Date: 2020/6/9 17:36
     */
    public class SingleThreadPool {
    
        private static class ThreadPoolHolder {
            private static ThreadPoolExecutor pool = new ThreadPoolExecutor(20, 200, 60L, TimeUnit.SECONDS, new SynchronousQueue());
        }
    
        public static ThreadPoolExecutor getInstance() {
            return ThreadPoolHolder.pool;
        }
    }
    
    

    直接通过 

    SingleThreadPool.getInstance() 获取线程池实例


    备注:也可以通过ioc容器管理,标记成单例模式(更简单),理论上ioc管理的单例,不是真正的单例,因为控制不了其他人员使用new的方式创建
     
     
  • 相关阅读:
    软工假期预习作业1
    2号团队-团队任务4:每日立会(汇总)
    2号团队-团队任务4:每日立会(2018-11-26)
    2号团队-团队任务4:每日立会(2018-11-27)
    第二小组首次会议记录
    第二次作业
    自我介绍+课后作业1:准备
    Linux安装redis
    Redis面试题
    Mybatis面试题
  • 原文地址:https://www.cnblogs.com/draymond/p/12323567.html
Copyright © 2020-2023  润新知