• 170601、单例模式的三种水平代码(第三种最佳)


    一、单例模型具备条件:

    1、私有的构造方法

    2、instance(单一实例,static)和getInstance(获取实例的方法,static)必须是static

    二、下面三种不同层次单例模型代码评价:

    第一种,通过测试发现,虚拟机加载类的时候单例就会被初始化,有些比较费时的类,我们需要使用时才加载(比如:数据库连接,开机加速等),这时候就不太适合用这种方式

    第二种,通过测试发现虚拟机加载类的时候不会初始化,只有调用了获取实例的方法时才会实例化,如果已经实例化的直接拿来用,实现了懒加载,但采用了synchronized同步的方式,性能会有所下降

    第三种,通过测试发现,实现了懒加载的功能(静态内部类),也解决了第二种性能下降的问题。其实代理模型等也是可以实现的

    三、总结:我们可以通过优化代码来实现性能最佳的单例模型类。推荐使用第三种方式,如果不是很费时的单例第一种也没关系。今天不举spring或jdk单例模型的实现,因为单例很好理解。值得注意的是,通过反射强制访问等,可能会破坏单例,但是是有办法避免的,后面有机会再做介绍。

    四、单例模型未优化的例子(原始)

    public class Singleton {
        //static
        private static Singleton instance = new Singleton();
        //私有构造方法
        private Singleton() {
        }
        //static
        public static Singleton getInstance() {
            return instance;
        }
    }

    五、下面是三种不同水平的单例代码(第三种性能最佳)

    1)第一种:(上例及下面这个例子分析),虚拟机加载的时候就会初始化

    public class SingletonObject {
            private static SingletonObject instance = new SingletonObject();
            private SingletonObject() {
            System.out.println("SingletonObject is created");
        }
        
        public static SingletonObject getInstance() {
            return instance;
        }

    //单独调用此方法(SingletonObject.otherMethod())时,”SingletonObject is created“也会被打印,说明虚拟机加载的时候就会初始化

    public static void otherMethod() {
            System.out.println("this is other method");
    }

    2)第二种:使用synchronized同步,虚拟机加载的时候不初始化,调用getInstance方法时才初始化

    public class LazilySingletonObject {
        private static LazilySingletonObject instance = null;
        private LazilySingletonObject() {
            System.out.println("LazilySingletonObject is created");
        }
        /*
         * 这里必须同步锁synchronized
         */
        public static synchronized LazilySingletonObject getInstance() {
            if (null == instance) {
                instance = new LazilySingletonObject();
            }
            return instance;
        }

    //单独调用此方法(LazilySingletonObject.otherMethod())时,"LazilySingletonObject is created"不会被答应,说明单例没有实例化

    public static void otherMethod() {
      System.out.println("this is other method");
    }

    3)第三种:使用静态内部类实现赖加载,不使用synchronized,这样可以优化性能

    public class OptimizedLazilySingletonObject {
    
        private OptimizedLazilySingletonObject() {
            System.out.println("OptimizedLazilySingletonObject is created");
        }
        //静态内部类中持有这个对象
        private static class SingletonHolder {
            private static OptimizedLazilySingletonObject instance = new OptimizedLazilySingletonObject();
        }
        
        public static OptimizedLazilySingletonObject getInstance() {
            return SingletonHolder.instance;
        }
        
    }

    六、测试

    public class SingletonTest {
    
        public static void main(String[] args) {
            /**
             * 输出:Singleton is created
             * 说明获取对象的时候私有方法需要调用(很好理解)
             */
            //Singleton.getInstance();
            /**
             * 输出:SingletonObject is created
             *         this is other method
             * 说明:即使调用这个类中的其他方法,类也会立即初始化
             *         如果对于那种非常费时的初始化我们希望是用的时候才初始化(比如数据库连接等)
             */
            SingletonObject.otherMethod();
            /**
             * 实现了赖加载,使用的时候才初始化,但是使用同步锁,性能会下降
             */
            //LazilySingletonObject.getInstance();
            /**
             * 输出:this is other method
             * 说明:不用的时候,单例不会初始化
             */
            LazilySingletonObject.otherMethod();
            /**
             * 实现了赖加载,并没有影响性能
             */
            OptimizedLazilySingletonObject.getInstance();
        }
        
    }
  • 相关阅读:
    php文件下载原理
    spring源码@configuration&@bean
    解决java在idea运行正常,但是打成jar包后中文乱码问题
    IntelliJ IDEA查看堆内存和类继承关系
    jenkins无法展示报告
    解决windows(slave)导致linux(master)输出乱码
    UIRECODER安装记录
    vue项目前后端部署
    django orm
    django笔记
  • 原文地址:https://www.cnblogs.com/zrbfree/p/7273544.html
Copyright © 2020-2023  润新知