• 面试突击50:单例模式有几种写法?


    单例模式是面试中的常客了,它的常见写法有 4 种:饿汉模式、懒汉模式、静态内部类和枚举,接下来我们一一来看。

    1.饿汉模式

    饿汉模式也叫预加载模式,它是在类加载时直接创建并初始化单例对象,所以它并不存在线程安全的问题。它是依靠 ClassLoader 类机制,在程序启动时只加载一次,因此不存在线程安全问题,它的实现代码如下:

    public class Singleton {
        // 1.防止外部直接 new 对象破坏单例模式
        private Singleton() {}
        // 2.通过私有变量保存单例对象
        private static Singleton instance = new Singleton();
        // 3.提供公共获取单例对象的方法
        public static Singleton getInstance() {
            return instance;
        }
    }
    

    优点:实现简单、不存在线程安全问题。
    缺点:类加载时就创建了对象,创建之后如果没被使用,就造成了资源浪费的情况。

    2.懒汉模式

    懒汉模式和饿汉模式正好是相反的,所谓的懒汉模式也就是懒加载(延迟加载),指的是它只有在第一次被使用时,才会被初始化,它的实现代码如下:

    public class Singleton {
        // 1.防止外部直接 new 对象破坏单例模式
        private Singleton() {}
        // 2.通过私有变量保存单例对象
        private static volatile Singleton instance = null;
        // 3.提供公共获取单例对象的方法
        public static Singleton getInstance() {
            if (instance == null) { // 第一次效验
                synchronized (Singleton.class) {
                    if (instance == null) { // 第二次效验
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

    懒汉模式使用的是双重效验锁和 volatile 来保证线程安全的,从上述代码可以看出,无论是饿汉模式还是懒汉模式,它们的实现步骤都是一样的:

    1. 创建一个私有的构造方法,防止其他调用的地方直接 new 对象,这样创建出来的对象就不是单例对象了。
    2. 创建一个私有变量来保存单例对象。
    3. 提供一个公共的方法返回单例对象。

    懒汉模式相比于饿汉模式来说,不会造成资源的浪费,但写法要复杂一些。

    3.静态内部类

    静态内部类既能保证线程安全,又能保证懒加载,它只有在被调用时,才会通过 ClassLoader 机制来加载和初始化内部静态类,因此它是线程安全的,此模式的实现代码如下:

    public class Singleton {
        // 1.防止外部直接 new 对象破坏单例模式
        private Singleton() {
        }
    
        // 2.静态内部类
        private static class SingletonHolder {
            private static final Singleton INSTANCE = new Singleton();
        }
    
        // 3.提供公共获取单例对象的方法
        public static final Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
    }
    

    4.枚举

    枚举也是在第一次被使用时,才会被 Java 虚拟机加载并初始化,所以它也是线程安全的,且是懒加载的,它的实现代码如下:

    public enum  EnumSingleton {
        INSTANCE;
        public EnumSingleton getInstance(){
            return INSTANCE;
        }
    }
    

    总结

    单例模式适用于经常被访问的对象,或是创建和销毁需要调用大量资源和时间的对象,使用单例模式可以避免频繁创建和销毁对象。单例模式的常用实现方法有 4 种:饿汉模式、懒汉模式、静态内部类和枚举。从写法的简洁性、线程安全性和代码的易懂性等方面综合来看,博主比较推荐使用枚举或懒汉模式来实现单例模式。

    是非审之于己,毁誉听之于人,得失安之于数。

    公众号:Java面试真题解析

    面试合集:https://gitee.com/mydb/interview

  • 相关阅读:
    直接从国家统计局上找数据,并分析人口数据变化,做成可视化图
    Python爬虫:爬取某日头条某瓜视频,有/无水印两种方法
    教你如何爬取美团网数据,就是那么的简单
    你所在的城市空气质量如何?用Python可视化分析空气质量
    Python爬取股票数据,让你感受一下什么是一秒钟两千条数据
    小伙用Python制作一个小游戏,结果6秒就结束,怎么难玩?
    Python数据可视化:一张很漂亮的商业图
    反射练习题1
    字符串格式化总结补充与有序字典
    反射应用实例:importlib模块
  • 原文地址:https://www.cnblogs.com/vipstone/p/16300423.html
Copyright © 2020-2023  润新知