• 单例模式之懒汉模式和饿汉模式


    单例模式

    定义
    保证全局绝对只有一个实例对象
    单例类必须自己创建自己的唯一实例
    单例必须给所有其他对象提供这一实例

    单例的实现方式

    饿汉模式

    类加载时就实例化对象

    /*
        饿汉单例模式
        特征 类加载时就实例化对象
        优点 线程安全 还没线程时就实例化了 所以线程绝对安全的
        缺点 可能会带来内存浪费占茅坑不拉屎的想象  适用于实例数量少的场景
    */
    public class HungrySingleton {
        // 类加载顺序 先静态后动态 先属性后方法 先上后下
        
        // 类加载时就会被实例化
    	private static HungrySingleton instance = new HungrySingleton();
    	
        // 构造函数必须私有 这样才不会被外部对象实例化
        private HungrySingleton(){}
        
        // 获取唯一可用的对象 (获取实例有则返回无则创建) static让全局可访问
        public static HungrySingleton getInstance() {
            return instance;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    懒汉模式

    被外部类调用时才初始化实例
    
    • 1
    /**
     * 懒汉模式
     * 特征 被外部类调用时才初始化实例
     * 优点 不浪费内存 不提前初始化 用时再初始化
     * 缺点 多线程下不安全 
     *
     */
    public class LazySingleton {
        
        private static LazySingleton instance = null;
    
        LazySingleton(){ }
        
        public static LazySingleton getInstance() {
            if(null==instance){
                instance =  new LazySingleton();
            }
            return instance;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    懒汉模式升级 双重检查加锁 double-checked locking

    package com.liao.edu.lazy;
    /**
     * 懒汉模式+双重检查加锁
     * 特征 被外部类调用时才初始化实例
     * 优点 调用方法有条件触发锁 锁的粒度更细 线程安全的
     * 缺点 还是会触发锁,会被反序列化破坏
     */
    public class LazyDoubleCheckSingleton {
        //volatile  防止指令重拍
        //因为 instance =  new DoubleCheckLazySingleton(); 实例化过程并不是原子性的
        //所以加volatile防止指令重排(123顺序可能错乱 导致其他线程调用时instance!=null )
        private volatile static LazyDoubleCheckSingleton instance = null;
    
        //私有化保证不被外部初始化
        private  LazyDoubleCheckSingleton(){}
    
        public static  LazyDoubleCheckSingleton getInstance() {
            //有条件加锁避免调用就上锁 即减少同步锁的竞争
            if(null==instance){
                synchronized (LazyDoubleCheckSingleton.class){
                    //保证单例
                    if(null==instance){
                        instance =  new LazyDoubleCheckSingleton();//不是原子操作
                        //1.创建内存空间
                        //2.在内存空间内创建对象
                        //3.将内存空间复制给变量instance
                    }
                }
            }
            return instance;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    登记式/注册式单例之枚举单例

    package com.liao.edu.register;
    
    /**
     * 枚举单例
     *   枚举天生不能被反射破坏 Cannot reflectively create enum objects
     *   枚举天生线程安全 private volatile transient Map<String, T> enumConstantDirectory = null;
     *   优点  写法优雅简单 防止反射 线程安全
     *   缺点  底层是饿汉式的实现 内存浪费 不能大量使用
     */
    public enum EnumSingleton {
        INSTANCE;
        private  Object obj;
    
        public Object getObj() {
            return obj;
        }
    
        public void setObj(Object obj) {
            this.obj = obj;
        }
    
        public static EnumSingleton getInstance() {
            return INSTANCE;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    注册式单例之容器单例

    package com.liao.edu.register;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * 容器注册单例
     * 适用于单例非常多的情况,便于管理
     */
    public class ContainerSingleton {
    
        private static Map<String,Object> map  = new ConcurrentHashMap<String,Object>();
    
        //无参私有的构造函数
        private ContainerSingleton(){}
    
        public static Object getInstance(String className) {
            if(!map.containsKey(className)){
                synchronized (ContainerSingleton.class){
                    if(!map.containsKey(className)){
                        try{
                            map.put(className,Class.forName(className).newInstance());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            return  map.get(className);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    uni-app医院智能导诊系统源码
    基于微信中介看房预约小程序系统设计与实现 开题报告
    从零开始Blazor Server(7)--使用Furion权限验证
    有问题直接说问题,问什么在不在???
    Spring Boot应用程序安装为Unix、Linux、Windows操作系统服务
    信息安全相关标准
    解锁互联网安全的新钥匙:JWT(JSON Web Token)
    最强人工智能 OpenAI 极简教程
    PLM、ERP 和 MES,制造业的三剑客
    软考 系统架构设计师系列知识点之特定领域软件体系结构DSSA(2)
  • 原文地址:https://blog.csdn.net/loveme888/article/details/125546136