Android单例模式总结

定义

保证一个类只有一个实例,并提供一个全局访问点

具体写法

单例模式一般分为两种形式,第一种是饿汉式,第二种是懒汉式。(当然有很多其他的博客或者书写的说,单例模式还分为其他的什么枚举啊等形式,但是我们这里只讲主流的,也就是我们项目中用的最多的两种形式)
我们先来看看第一种饿汉式

public class Singleton_EHanShi {

    public static void main(String[] args) {

    }

}

/***
 * 这种单例模式叫做饿汉式
 *
 * 饿汉式是在类装载的时候进行实例化的,所以就不存在线程安全问题
 * 我们应该还记得static的作用
 * static:
 *  1.多个实例的static变量会共享同一块内存区域
 *  2.静态变量在类装载的时候就会进行初始化
 *
 * 缺点是:不管有没有用到这个对象,都会实例化出来
 *
 * 提问:类是什么时候装载的?
 * https://juejin.im/post/5d062ccc518825122925bc4b
 *
 * 类加载的步骤分为:加载--》验证--》准备--》解析--》初始化--》使用--》卸载
 * 静态变量实在初始化这一步执行的
 *
 *
 */
class Singletom {

    private static final Singletom mInstance = new Singletom();

    private Singletom(){}


    public static Singletom getInstance() {
        return mInstance;
    }

}

我们再来看看第二种懒汉式

注意:懒汉式和饿汉式有时候容易混淆,那我们怎么去记呢?
饿汉式:不管用不用,先创建放在哪里。不用考虑线程安全问题。在类装载的时候,就完成了实例化。(疑问:什么时候类装载)
饿汉式有什么缺点?可能会造成内存浪费,就是我都没用到这个类,你也给实例化出来了。那么怎么解决这个问题呢?也就是说可不可以我用到的时候再给我实例化呢?
于是就有了懒汉式。
懒汉式:当我们需要去使用这个类的时候,首次创建去使用才会创建这个对象。你要是没用到就不会去创建这个对象

public class Singleton_LanHanShi_Test1 {


    public static void main(String[] args) {


    }

}

/***
 * 这种方式会有线程安全问题,遇到多个线程的时候,不能保证类的只有一个实例
 */
class Singletom1 {

    private static Singletom1 instance;

    private Singletom1(){
    }

    public static Singletom1 getInstance() {
        if(instance == null) {
            instance = new Singletom1();
        }
        return instance;
    }

}

/***
 * 这种方式线程安全了,但是每次获取实例都要排队等待,所以会造成效率低,因为每次都要排队
 * 疑问:synchronized效率为什么会低?
 */
class Singletom2 {

    private static Singletom2 instance;

    private Singletom2(){}


    public static synchronized Singletom2 getInstance() {
        if(instance == null) {
            instance = new Singletom2();
        }
        return instance;
    }

}

/***
 * 这种方式最完美
 *
 * 疑问:1 为什么要双重校验?
 *      答:第一个判断null是为了解决以后不用每次都进入到同步代码块中,解决效率低的问题
 *         第二个判断null是为了解决首次如果多个线程都到达synchronized同步代码块这里,当第一个线程执行完实例化操作之后,第二个线程进入同步代码块
 *         这个时候是已经存在instance对象了,不需要再进行new的操作了。
 *
 * 2 为什么还要使用volatile关键字
 * 答:是为了将线程工作内存中的数据刷新到主内存中
 */
class Singletom3 {

    private static volatile Singletom3 instance;

    private Singletom3(){}

    public static Singletom3 getInstance() {
        if(instance == null) {
            synchronized(Singletom3.class) {
                if(instance == null) {
                    instance = new Singletom3();
                }
            }
        }
        return instance;
    }

}

最后我们还说一种静态内部类的实现单例的方式

public class Singleton_JingTaiNeiBuLei {
    
}

/***
 * 这里是采用静态内部类的方式来实现单例模式
 *
 * 静态内部类也能保证线程安全
 *
 */
class Singleton5 {

    private Singleton5(){}

    private static class SingletonInstance {
        private static final Singleton5 INSTANCE = new Singleton5();
    }

    public static Singleton5 getInstance(){
        return SingletonInstance.INSTANCE;
    }

}

使用场景

1.需要频繁的进行创建和销毁的对象
2.创建时耗时过多或者耗费资源过大,但又经常用到的对象,比如频繁访问数据库或文件的对象
3.工具类

完!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值