美文网首页Android开发经验谈Android开发Android技术知识
Android面试:单例模式一共几种?优缺点分别是什么?运行速度

Android面试:单例模式一共几种?优缺点分别是什么?运行速度

作者: 字节走动_Android | 来源:发表于2020-09-14 22:06 被阅读0次

    单例模式:单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

    单例模式主要有三种:

    分别是懒汉式单例,饿汉式单例,登记式单例(懒汉模式变种,使用静态内部类创建)。

    1.懒汉式单例
    /**
     * 这个是懒汉模式,线程安全的
     */
    public class Singleton {
        private static Singleton singleton;
        private Singleton() {}  //此类不能被实例化
        // 加上 synchronized 保证创建线程线程安全
        public static synchronized Singleton getInstance() {
            if (singleton == null) {
                singleton = new Singleton();
            }
            return singleton;
        }
    }
    
    

    优点:第一次调用才初始化,避免内存浪费。
    缺点:必须加锁synchronized 才能保证单例,(如果两个线程同时调用getInstance方法,会chuxia)但加锁会影响效率。

    2.饿汉式单例
    /**
     * 这个是饿汉模式,类一加载就要初始化
     */
    public class SingletonDemo3 {
    
        // 在成员变量声明的时候就要初始化
        private static SingletonDemo3 instance = new SingletonDemo3();
    
        private SingletonDemo3() {
    
        }
    
        public static SingletonDemo3 getInstance() {
            // 若当前实例为空,重新指向一个新的实例
            if (instance == null) {
                instance = new SingletonDemo3();
    
            }
            return instance;
        }
    }
    

    优点:没有加锁,执行效率会提高。
    缺点:类加载时就初始化,浪费内存。

    3.登记式模式(holder)

    内部类只有在外部类被调用才加载,产生Singleton实例;又不用加锁。此模式有上述两个模式的优点,屏蔽了它们的缺点,是最好的单例模式。

    /**
     * 这个是懒汉模式变种,使用静态内部类创建
     */
    public class SingletonDemo4 {
    
        private static class SingletonHolder{
            private static final SingletonDemo4 instance = new SingletonDemo4();
        }
    
        private SingletonDemo4() {
    
        }
    
        public static SingletonDemo4 getInstance() {
            // 调用内部类的属性创建新的实例
            return SingletonHolder.instance;
        }
    }
    

    静态内部类这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,它跟前几种方式不同的是:Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载,另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化instance显然是不合适的。这个时候,这种方式相比饿汉方法就显得更合理。

    若单例对象占用资源少,不需要延迟加载,那么使用枚举好于饿汉式,因为枚举十分安全,耗时差不多。

    若单例对象占用资源多,需要延迟加载,那么使用内部类好于懒汉式,耗时差距明显。

    对文章有何见解,或者有何技术问题,都可以在评论区一起留言讨论,一定会回复的。
    也欢迎大家来我的B站找我玩,各类Android架构师进阶技术难点的视频讲解,任君白嫖。
    B站直通车:https://space.bilibili.com/484587989

    相关文章

      网友评论

        本文标题:Android面试:单例模式一共几种?优缺点分别是什么?运行速度

        本文链接:https://www.haomeiwen.com/subject/npmtyktx.html