Android开发中无处不在的设计模式——单例模式

本文介绍了单例模式的概念及其在Android开发中的应用。通过详细的代码示例展示了如何实现线程安全的单例模式,并讨论了其在内存管理和性能优化方面的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次。而在android开发中,必要的了解一些设计模式又是非常有必要的。对于想系统的学习设计模式的同学,这里推荐2本书。一本是Head First系列的Head Hirst Design Pattern,英文好的可以看英文,可以多读几遍。另外一本是大话设计模式。

这篇文章介绍一个模式,就是单例模式,因为个人觉得这个模式理解起来最容易,而且不是太复杂。

首先了解一些什么是单例,从名字中就可以听出来就是在内存中维护唯一对象。这样做有以下几个优点
对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中。
保持程序运行的时候该中始终只有一个实例存在内存中
其实单例有很多种实现方式,但是个人比较倾向于其中1种。可以见单例模式

代码如下

public class Singleton {
    private static volatile Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() { 
        Singleton inst = instance;
        if (inst == null) {
            synchronized (Singleton.class) {
                if (inst == null) {
                    inst = new Singleton();
                    instance = inst;
                }
            }
        }
        return inst;
    }
}

要保证单例,需要做一下几步

必须防止外部可以调用构造函数进行实例化,因此构造函数必须私有化。
必须定义一个静态函数获得该单例
单例使用volatile修饰
使用synchronized 进行同步处理,并且双重判断是否为null,我们看到synchronized (Singleton.class)里面又进行了是否为null的判断,这是因为一个线程进入了该代码,如果另一个线程在等待,这时候前一个线程创建了一个实例出来完毕后,另一个线程获得锁进入该同步代码,实例已经存在,没必要再次创建,因此这个判断是否是null还是必须的。
至于单例的并发测试,可以使用CountDownLatch,使用await()等待锁释放,使用countDown()释放锁从而达到并发的效果。可以见下面的代码

public static void main(String[] args) {
    final CountDownLatch latch = new CountDownLatch(1);
    int threadCount = 1000;
    for (int i = 0; i < threadCount; i++) {
        new Thread() {
            @Override
            public void run() {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Singleton.getInstance().hashCode());
            }
        }.start();
    }
    latch.countDown();
}

看看打印出来的hashCode会不会出现不一样即可,理论上是全部都一样的。

public class Singleton {

   private static Singleton mInstance = null;

   private Singleton() {

   }

 /**
         * 方式二 : 在第一次加载SingletonHolder时初始化一次mOnlyInstance对象, 保证唯一性, 也延迟了单例的实例化,
         * 如果该单例比较耗资源可以使用这种模式.
         * 
         * @return
     */
    public static Singleton getInstanceFromHolder() {
            return SingletonHolder.mOnlyInstance;
    }

/**
 * 静态内部类
 * 
 * @author mrsimple
 */
private static class SingletonHolder {
        private static final Singleton mOnlyInstance = new Singleton();
}   

}
而在Android中,很多地方用到了单例。

比如Android-Universal-Image-Loader中的单例

private volatile static ImageLoader instance;
/** Returns singleton class instance */
public static ImageLoader getInstance() {
    if (instance == null) {
        synchronized (ImageLoader.class) {
            if (instance == null) {
                instance = new ImageLoader();
            }
        }
    }
    return instance;
}

上面的单例都是比较规规矩矩的,当然实际上有很多单例都是变了一个样子,单本质还是单例。

最后,我们应用一下单例模式。典型的一个应用就是管理我们的Activity,下面这个可以作为一个工具类,代码也很简单,也不做什么解释了。

public class ActivityManager {

private static volatile ActivityManager instance;
private Stack<Activity> mActivityStack = new Stack<Activity>();

private ActivityManager(){

}

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

public void addActicity(Activity act){
    mActivityStack.push(act);
}

public void removeActivity(Activity act){
    mActivityStack.remove(act);
}

public void killMyProcess(){
    int nCount = mActivityStack.size();
    for (int i = nCount - 1; i >= 0; i--) {
        Activity activity = mActivityStack.get(i);
        activity.finish();
    }

    mActivityStack.clear();
    android.os.Process.killProcess(android.os.Process.myPid());
}

}

详细介绍请参见:https://race604.com/java-double-checked-singleton/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值