• 设计模式——单例模式


    单例模式定义:保证创建唯一实例。

    实现有很多方式但是有一个共同点:构造方法私有化。

    单例模式实现需要考虑的问题:

    • 保证单例
    • 延迟加载
    • 线程安全
    • 反反射、反序列化、反克隆

    下面各种实现方式就是上述问题的渐进解决。懒汉式+双重验证锁是最常用的。

    一、饿汉式

    public class SingletonV0 {
        //利用一个类只会被类加载一次创建唯一实例
        private static final SingletonV0 INSTANCE = new SingletonV0();
    
        private SingletonV0(){}
    
        public static SingletonV0 getSingletonVo(){
            return INSTANCE;
        }
    }

    二、懒汉式

    public class SingletonV1 {
    
        private static SingletonV1 INSTANCE;
    
        private SingletonV1(){}
    
        public static SingletonV1 getInstance(){
            if (INSTANCE == null){
                //延迟加载
                INSTANCE = new SingletonV1();
            }
            return INSTANCE;
        }
    }

    三、懒汉式+双重验证锁——最常用的方式

    public class SingletonV2 {
        /**
         * 注意细节:volatile修饰
         */
        private static volatile SingletonV2 INSTANCE;
    
        private SingletonV2(){}
    
        public static SingletonV2 getInstance(){
            //双重验证锁
            if (INSTANCE == null){
                synchronized (SingletonV2.class){
                    if (INSTANCE == null){
                        INSTANCE = new SingletonV2();
                    }
                }
            }
            return INSTANCE;
        }
    }

    四、懒汉式+双重验证锁+反反射+反序列化+反克隆

    public class SingletonV3 implements Cloneable, Serializable {
        /**
         * 注意细节:volatile修饰
         */
        private static volatile SingletonV3 INSTANCE;
    
        private static boolean IS_FIRST_CREATE = true;
        private SingletonV3(){
            //反反射
            if (IS_FIRST_CREATE){
                synchronized (SingletonV3.class){
                    if (IS_FIRST_CREATE){
                        IS_FIRST_CREATE = false;
                    }
                }
            }else{
                throw new UnsupportedOperationException("singleton object is already init().");
            }
        }
    
        public static SingletonV3 getInstance(){
            //双重验证锁
            if (INSTANCE == null){
                synchronized (SingletonV3.class){
                    if (INSTANCE == null){
                        INSTANCE = new SingletonV3();
                    }
                }
            }
            return INSTANCE;
        }
    
        /**
         * 反克隆
         */
        @Override
        protected Object clone() throws CloneNotSupportedException {
            throw new CloneNotSupportedException("singleton object not support clone");
        }
        /**
         * 反序列化
         */
        private void readObject(ObjectInputStream in) throws InvalidObjectException {
            throw new InvalidObjectException("can't deserialize singleton");
        }
    
        private void readObjectNoData() throws InvalidObjectException {
            throw new InvalidObjectException("can't deserialize singleton");
        }
    }

    五、内部静态类

    public class SingletonV4 {
    
        private SingletonV4(){}
    
        /**
         * 利用静态内部类的延迟加载
         */
        private static class SingletonHolder{
            private static final SingletonV4 INSTANCE = new SingletonV4();
        }
    
        public SingletonV4 getInstance(){
            return SingletonHolder.INSTANCE;
        }
    }

    六、枚举类

    用枚举类创建单例是《effective Java》中推荐使用的方法。

    枚举类的实质是编译器的一个语法糖,反编译后的代码:java枚举类语法糖

    public enum SingletonV5 {
    
        /**
         * Java的枚举类型其实是一个编译期的一个语法糖
         *  enum 编译后public final class
         *  INSTANCE  编译后 public static final SingletonV5 INSTANCE;
         *  静态块初始化+反克隆+反序列化
         */
        INSTANCE;
    
    }

    七、框架中的单例模式

    1、Spring单例Bean

    Spring中单例模式非常多,基本都是使用懒汉式+双重验证锁的方式创建单例的

    最有代表性的实现:Spring单例Bean。

    /* org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean) */
        protected Object getSingleton(String beanName, boolean allowEarlyReference) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
                synchronized (this.singletonObjects) {
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    if (singletonObject == null && allowEarlyReference) {
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            singletonObject = singletonFactory.getObject();
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
            return singletonObject;
        }
  • 相关阅读:
    [Python接口自动化]从零开始学习python自动化(1):环境搭建
    转载:python + requests实现的接口自动化框架详细教程
    转载:selenium的wait.until()
    转载:selenium webdriver定位不到元素的五种原因及解决办法
    关于xpath语句完全正确,但是页面报错: no such element: Unable to locate element: {"method":"xpath","selector":"xpath"}
    BDD测试之selenium控制滚动条
    阿里云 -- 2万并发用户方案
    关于语音合成和识别
    在线浏览文档的方案
    关于全文搜索引擎
  • 原文地址:https://www.cnblogs.com/wqff-biubiu/p/12626781.html
Copyright © 2020-2023  润新知