彻底明白Android设计模式—单例模式

彻底明白Android设计模式—单例模式,第1张

概述这次讲讲最简单也最常用的单例模式(顾名思义保证实例唯一的一种设计模式)直接五种单例模式献上,让你了解单例模式的前世今生饿汉模式像一个饿汉一样,不管需不需要,有没有,都一定要去创建实例。因为太饿了,不管三七二十一,我就要吃!!! /*一、饿汉模式*/privatestaticSingl

这次讲讲最简单也最常用的单例模式(顾名思义 保证实例唯一的一种设计模式)

直接五种单例模式献上,让你了解单例模式的前世今生

饿汉模式

像一个饿汉一样,不管需不需要,有没有,都一定要去创建实例。因为太饿了,不管三七二十一,我就要吃!!!

	/*一、饿汉模式*/    private static Singleton singleton = new Singleton();    public static Singleton getSingleton() {        return singleton;    }

饿汉模式是在类初始化的时候就创建了实例,所以不管用不用都创建了实例,但是是线程安全的,因为静态变量的创建,在类的初始化过程中是保证线程安全的。

优点:线程安全,读取变量速度快缺点:因为一开始就创建了变量,如果后面没用到,就有可能浪费资源懒汉模式 (不考虑线程安全)

像一个懒汉一样,需要的时候才去实例化,不需要我就不实例化。

    /*二、懒汉模式-线程不安全模式*/    private static Singleton singleton2;    public static Singleton getSingleton2() {        if (singleton2 == null) {            singleton2 = new Singleton();        }        return singleton2;    }
优点:需要的时候才会实例化变量,实现懒加载缺点:线程不安全懒汉模式 (线程安全)

这种较上面升级了一点,就是考虑到线程安全,当两个线程同时 *** 作怎么办,肯定要加锁啦

    /* 三、懒汉模式-线程安全模式     * 增加synchronized实现实例同步     * */    private static Singleton singleton3;    public synchronized static Singleton getSingleton3() {        if (singleton3 == null) {            singleton3 = new Singleton();        }        return singleton3;    }

synchronized修饰符保证同一时间只有一个线程能进入该方法

优点:线程安全,懒加载缺点:需要每次都走锁的部分,性能不算很好双重加锁

这种就是我们代码中常用的啦,双重加锁的同时,用volatile修饰变量

	private volatile static Singleton singleton4;    public static Singleton getSingleton4() {        if (singleton4 == null) {            synchronized (Singleton.class) {                if (singleton4 == null) {                    singleton4 = new Singleton();                }            }        }        return singleton4;    }

这种模式在保证线程安全的同时提高了性能:

synchronized加锁使得同一时间只有一个线程能进入

外面又加了一层if判断其实就是为了性能,如果不为空就不需要进入下面锁的部分了,直接返回

volatile修饰符为了让singleton4实例在变化后立即写入主存,方便其他线程读取,否则有可能造成空指针,因为new的过程不是一瞬间的,所以有可能在 *** 作过程中,另一个线程读到singleton4还是空的。

优点:线程安全,懒加载,性能也还可以

缺点:有点复杂,可能加载速度不快

静态内部类模式-号称最优雅单例

这种方法精髓就在于比较优雅,代码量少,简单易懂。
第一次调用方法时候,才会去加载SingletonHolder内部类并且实例化INSTANCE

    private static class SingletonHolder {        private static final Singleton INSTANCE = new Singleton();    }    public static Singleton getSingleton5() {        return SingletonHolder.INSTANCE;    }

ok,你说只会存在一个实例我是看到了,但是这个为啥就能保证线程安全了呢?

这就要说到类的初始化了,类初始化阶段是类加载过程的最后一步,也是执行类构造器()方法的过程。
而虚拟机会保证一个类的()方法在多线程环境中被正确地加锁和同步。如果有多个线程去同时初始化一个类,那么只会有一个线程去执行这个类的()方法,其它线程都需要阻塞等待,直到活动线程执行()方法完毕。
所以,明白了吧,内部类在初始化过程中是线程安全的,所以就能保证这个单例的创建也是线程安全的。

优点:线程安全,懒加载,代码量少,简单易懂缺点:在调用getSingleton5方法不能带上参数进行实例化,比如上下文参数Context在AndroID中的应用

应该随处可见吧,当某个实例在app中被多次调用,就需要创建一个单例,不让其多次创建。
一般就选用双重加锁或者静态内部类模式即可。

总结

以上是内存溢出为你收集整理的彻底明白Android设计模式—单例模式全部内容,希望文章能够帮你解决彻底明白Android设计模式—单例模式所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1062099.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存