单例模式

Java中单例(Singleton)模式是一种广泛使用的设计模式。单例模式的主要作用是保证在Java程序中,某个类只有一个实例存在。

一、单例模式的特点

  1. 单例类只能有一个实例。
  2. 单例类必须自己传教自己的唯一实例
  3. 单例类必须给所有其他对象提供这一实例

单例模式保证了全局对象的唯一性,比如系统启动读取配置文件就需要单例保证配置的一致性


二、实现单例模式的六种方式

  1. 饿汉式---静态常量
    public class HungrySingleton {
        // 2.创建类内静态属性为该类对象,并使用final和private进行修饰,避免其能够修改
        private static final HungrySingleton HUNGRY_SINGLETON = new HungrySingleton();
    
        // 1.将构造方法私有
        private HungrySingleton() {
    
        }
        // 3.将这一个单例使用静态方法返回到调用者手中
        public static HungrySingleton getInstance() {
            return HUNGRY_SINGLETON;
        }
    }
    
    • 优点:写法简单,在类装载的时候就完成了实例化,避免了线程同步问题。
    • 缺点:如果从始至终未使用过这个实例,会造成内存的浪费。没有懒加载的效果
  2. 饿汉式---静态代码块
    public class StaticCodeBlockSingleton {
        private static final StaticCodeBlockSingleton STATIC_CODE_BLOCK_SINGLETON;
        static {
            STATIC_CODE_BLOCK_SINGLETON = new StaticCodeBlockSingleton();
        }
        private StaticCodeBlockSingleton() {
    
        }
        public static StaticCodeBlockSingleton getInstance() {
            return STATIC_CODE_BLOCK_SINGLETON;
        }
    }
    

    这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。

  3. 饿汉式---枚举类
    public enum EnumSingleton {
        //枚举元素本身就是单例
        SINGLETON;
    
        //添加自己需要的操作
        public void singletonOperation(){
        }
    }
    
    • 线程安全,调用效率高,可以天然的防止反射和反序列化调用。
    • 不能延时加载,没有懒加载的效果
  4. 懒汉式---同步方法,线程安全
    public class LazySingleton {
        private static LazySingleton lazySingleton = null;
    
        //保证无法通过构造器进行外部实例化
        private LazySingleton() {
    
        }
    
        public static synchronized LazySingleton getInstance() {
            if (lazySingleton == null) {
                lazySingleton = new LazySingleton();
            }
            return lazySingleton;
        }
    }
    
    • 优点:该模式的特点是类加载时没有生成单例,只有当第一次调用 getlnstance ()方法时才去开辟内存空间,创建这个单例,线程安全。
    • 缺点:高并发的情况下,每次访问getlnstance ()方法都要同步,会影响性能,且消耗更多的资源。
  5. 懒汉式---同步代码块,双重检查
    public class DoubleCheckLockSingleton {
        private static DoubleCheckLockSingleton dclSingleton = null;
    
        private DoubleCheckLockSingleton() {
    
        }
    
        public static DoubleCheckLockSingleton getInstance() {
            //最外层检查是为了效率,后续线程进来发现该类实例已经创建,直接获取
            if (dclSingleton == null) {
                synchronized (DoubleCheckLockSingleton.class) {
                    if (dclSingleton == null) {
                        dclSingleton = new DoubleCheckLockSingleton();
                    }
                }
            }
            return dclSingleton;
        }
    }
    
    • 优点:线程安全;延迟加载;效率较高。

    如代码中所示,我们进行了两次if (dclSingleton == null)检查,这样,同步代码块中的实例化代码只用执行一次,后面再次访问时,判断if (dclSingleton == null),直接return实例化对象。

  6. 懒汉式---静态内部类
    public class StaticInnerClassSingleton {
        private StaticInnerClassSingleton() {
        }
    
        public static StaticInnerClassSingleton getInstance() {
            return SingletonClassInstance.INSTANCE;
        }
    
        private static class SingletonClassInstance{
            private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
        }
    }
    
    • 优点:静态内部类方式在StaticInnerClassSingleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance()方法,才会装载SingletonClassInstance静态内部类,从而完成StaticInnerClassSingleton的实例化。线程安全,调用效率高,可以延时加载。
    • 缺点:不能保证反序列化的对象是单例。
posted @   喜欢你笑_容  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示