• Java 单例模式双重判断、内部类、枚举


    ================================

    ©Copyright 蕃薯耀 2022-05-20

    https://www.cnblogs.com/fanshuyao/

    一、饿汉模式

     
    public class Hunger {
     
        /**
         * 增加final关键字,避免被修改
         */
        private static final Hunger hunger = new Hunger();
        
        /**
         * 私有化,避免创建对象
         */
        private Hunger() {};
        
        /**
         * 提供获取对象的方法
         * @return
         */
        public static Hunger get() {
            return hunger;
        }
        
        
    }

    二、饿汉模式(静态块)

    可以通过配置文件对实例进行初始化

     
    import lqy.utils.PropertiesUtils;
     
    public class HungerStatic {
     
     
        private static final HungerStatic hungerStatic;
        
        private String name;
        
        /**
         * 私有化,避免创建对象
         */
        private HungerStatic(String name) {
            this.name = name;
        };
        
        
        static {
            String name = PropertiesUtils.readKeyValue("config.properties", "name");
            hungerStatic = new HungerStatic(name);
        }
        
        
        /**
         * 提供获取对象的方法
         * @return
         */
        public static HungerStatic get() {
            //System.out.println(hungerStatic);
            return hungerStatic;
        }
     
     
        /*
        @Override
        public String toString() {
            return "HungerStatic [name=" + name + "]";
        }
        */
        
        
    }

    三、懒汉模式 - 同步方法

    public class LazySafe {
     
        private static LazySafe lazySafe;
        
        private LazySafe() {}
        
        public static synchronized LazySafe get() {
            if(lazySafe == null) {
                lazySafe = new LazySafe();
            }
            
            return lazySafe;
        }
        
    }

    四、懒汉模式 - 同步块

     
    public class LazySync {
     
        /**
         * 需要加volatile防止指令重排
         */
        private static volatile LazySync lazySync;
        
        private LazySync() {}
        
        public static LazySync get() {
            synchronized (LazySync.class) {
                if(lazySync == null) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lazySync = new LazySync();
                }
            }
            return lazySync;
        }
    }

    五、懒汉模式 - 双重判断

     
    public class LazySyncDouble {
     
        /**
         * 需要加volatile防止指令重排
         */
        private static volatile LazySyncDouble lazySyncDouble;
        
        private LazySyncDouble() {}
        
        public static LazySyncDouble get() {
            if(lazySyncDouble == null) {
                synchronized (LazySyncDouble.class) {
                    if(lazySyncDouble == null) {
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        lazySyncDouble = new LazySyncDouble();
                    }
                }
            }
            return lazySyncDouble;
        }
    }

    六、懒汉模式 - 内部类

     
    /**
     * Inner是一个内部静态类,当外部类 LazyInner 被加载的时候,并不会创建 Inner实例对象。
     * 只有当调用 get() 方法时,Inner才会被加载,这个时候才会创建 instance。
     * instance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。
     * 所以,这种实现方法既保证了线程安全,又能做到延迟加载。
     * @author islee
     *
     */
    public class LazyInner {
     
        private LazyInner() {}
        
        /**
         * 静态内部类
         *
         */
        private static class Inner{
            private static final LazyInner lazyInner = new LazyInner();
        }
        
        public static LazyInner get() {
            return Inner.lazyInner;
        }
    }

    七、枚举【最安全方式】

    最安全,能预防反射和反序列化的安全问题

     
    /**
     * Java虚拟机会保证枚举类型不能被反射并且构造函数只被执行一次。
     * [最安全],其他的会存在反射和反序列化的安全问题
     *
     */
    public class SingletonEnum {
     
        private SingletonEnum() {}
        
        private enum SingletonHolder {
     
            INSTANCE;
            
            private final SingletonEnum singletonEnum;
            
            private SingletonHolder() {
                singletonEnum = new SingletonEnum();
            }
            
            private SingletonEnum get() {
                return singletonEnum;
            }
        }
        
        
        public static SingletonEnum get() {
            return SingletonHolder.INSTANCE.get();
        }
        
    }

    测试:

     
    import lqy.design.singleton.SingletonEnum;
     
    public class SingletonEnumTest {
     
        public static void singletonEnum() {
            long startTime = System.currentTimeMillis();
            
            for(int i=0; i<15; i++){
                new Thread(()-> {
                    System.out.println(SingletonEnum.get());
                }).start(); 
            }
            
            long endTime = System.currentTimeMillis();
            System.out.println("耗时:" + (endTime - startTime));
        }
        
        public static void main(String[] args) {
            singletonEnum();
            
        }
    }

    (时间宝贵,分享不易,捐赠回馈,^_^)

    ================================

    ©Copyright 蕃薯耀 2022-05-20

    https://www.cnblogs.com/fanshuyao/

     
  • 相关阅读:
    ecplise 导出maven项目依赖的jar
    vue.js 中组件的使用
    爬虫:python采集豆瓣影评信息并进行数据分析
    Python爬取前程无忧十万条招聘数据
    爬虫:新浪微博爬虫的最简单办法
    爬虫:利用python完成百度贴吧数据采集
    基于SSM框架的新生报到可视化系统
    爬虫:利用selenium采集某某环境网站的空气质量数据
    基于flask框架的高校舆情分析系统
    基于flask的城市空气质量分析系统
  • 原文地址:https://www.cnblogs.com/fanshuyao/p/16292885.html
Copyright © 2020-2023  润新知