Android 设计模式--单例模式

单例模式(Singleton Pattern)

以下内容大部分出自《设计模式》这本书

单例模式可以说是所有设计模式中最简单的模式,只需要一个类就可以完成。

单例模式定义:确保一个类只有一个实例,并提供一个全局访问点。

单例模式有什么用?

有一些对象我们只需要一个就够了,比如:线程池、缓存、对话框、用户信息设置等,这些对象只能有一个实例,如果出现多个实例可能到导致许多问题产生,例如:程序行为异常、资源使用过量、或者是不一致的结果。

单例模式是确保只有一个实例会被创建。单例模式以给了我们一个全局的访问点,和全局变量一样方便,又没有全局变量的缺点。全局变量的缺点即程序一开始就要创建好对象,如果这个对象非常消耗资源,而我们又不经常用到它,这就形成了浪费资源。

下面首先来写一种简单的单例模式

public class MyClass {

    /**
     * 利用静态变量来记录MyClass类的唯一实例
     */
    private static MyClass myClass;
    /**
     * 这里的构造函数私有化,防止别的类调用,只有内部才能调用来实例化
     */
    private MyClass(){}
    /**
     * 用getInstance()方法来实例化对象,并返回一个实例
     * @return
     */
    public static MyClass getInstance(){
        /**
         * 由于myClass是个静态变量,如果它为空表示该实例还没有被创建,我们就需要创建这个实例
         * 如果myClass不为空,就表示该实例已经存在,直接return myClass;
         */
        if(null==myClass){
            myClass=new MyClass();
        }
        return myClass;
    }
}
在使用的时候只需要调用 MyClass.getInstance()就可以获得到MyClass实例,也可以一定程度上防止MyClass多次被创建。但它是有缺陷的。

在多线程操作的时候有可能导致重复创建实例,当两个线程同时来调用MyClass.getInstance()的时候,由于myClass之前为null,所以两个线程会同时进入if条件内,创建两个实例。

解决多线程导致的问题就需要把getInstance()变成同步(synchronized)方法,代码如下

     /**
     * 通过synchronized关键字,我们迫使所有的线程进入到这个方法之前,要等到别的线程离开该方法。
     * @return
     */
    public static synchronized MyClass getInstance(){
        /**
         * 由于myClass是个静态变量,如果它为空表示该实例还没有被创建,我们就需要创建这个实例
         * 如果myClass不为空,就表示该实例已经存在,直接return myClass;
         */
        if(null==myClass){
            myClass=new MyClass();
        }
        return myClass;
    }

上面这种写法虽然解决了myClass被多次实例化问题,但是同步降低了性能。所以上面这种写法还是可以优化的。

如何优化?上面的写法每一次访问getInstance都会进行一次同步,所以会降低性能,那我们可以思考一下是不是每次getInstance都有必要进行同步呢?肯定不需要,我们使用同步是为了防止myClass对象被多次实例化,只有在myClass为null的时候才会去实例化,所以我们可以先做一步判断myClass是否为空,然后再同步

public static MyClass getInstance() {
    /**
     * 由于myClass是个静态变量,如果它为空表示该实例还没有被创建,我们就需要创建这个实例
     * 如果myClass不为空,就表示该实例已经存在,直接return myClass;
     */
    if (null == myClass) {
        synchronized (MyClass.class) {
            if (null == myClass) {
                myClass = new MyClass();
            }
        }
    }
    return myClass;
}

最后贴上完整代码

/**
 * Created by xu on 2017/3/8.
 */
public class MyClass {

    /**
     * 利用静态变量来记录MyClass类的唯一实例
     */
    private static MyClass myClass;

    /**
     * 这里的构造函数私有化,防止别的类调用,只有内部才能调用来实例化
     */
    private MyClass() {
    }

    /**
     * 用getInstance()方法来实例化对象,并返回一个实例
     *
     * @return
     */
    public static MyClass getInstance() {
        /**
         * 由于myClass是个静态变量,如果它为空表示该实例还没有被创建,我们就需要创建这个实例
         * 如果myClass不为空,就表示该实例已经存在,直接return myClass;
         */
        if (null == myClass) {
            /**
             * 同步锁
             */
            synchronized (MyClass.class) {
                if (null == myClass) {
                    myClass = new MyClass();
                }
            }
        }
        return myClass;
    }
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值