Android常用设计模式-单例模式

289 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Android中的单例模式

单例模式是设计模式最基本的吧,所有的设计模式应该也都是从单例模式开始的吧。

单例模式是我们最基本也是最常用的设计模式,通过单例模式我们可以保证系统中只有一个实例,在不同的地方调用都是这个实例!

下面看看如何使用Java和Kotlin分别定义单例模式吧。

一、饿汉式

在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。并且以后不再改变,其天生是线程安全的。但是缺点是稍微消耗资源。

class Singleton{  
    private static Singleton _instance = new Singleton();  
      
    private Singleton(){}  
      
    public static Instance getInstance(){  
        return _instance;  
    }  
} 

Kotlin的实现

object Singleton

是的我们最常用的object单例就是饿汉式的实现

二、懒汉式

懒汉式相比饿汉式的优点和缺点

优点:延迟加载(需要的时候才去加载)
缺点:线程不安全,在多线程中很容易出现不同步的情况

public class Singleton {
 
    private static Singleton instance = null;

    private Singleton() {
    }

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

Kotlin的实现

class Singleton private constructor() {
    companion object {
        private var instance: Singleton? = null
            get() {
                if (field == null) {
                    field = Singleton()
                }
                return field
            }
        fun get(): Singleton{
         return instance!!
        }
    }
}

三、加同步锁 + 双重检验锁

由于懒汉式会出现线程不安全的问题,那我们通过加同步锁来保证线程的安全,同时进行双重的判空避免造成不必要的同步开销。

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

kotlin的实现

class Singleton private constructor() {
    companion object {
        val instance: Singleton by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
        Singleton() 
        }
    }
}

四、内部类的实现

这种方式相比懒汉式和饿汉式的特点是延迟加载,线程安全,同时也减少了内存消耗。

public class SingletonInner {
 
    private static class SingletonHolder {
        private static SingletonInner instance = new SingletonInner();
    }
 
    private SingletonInner() {
    }
 
    public static SingletonInner getInstance() {
        return SingletonHolder.instance;
    }
 
}

Kotlin的实现

class SingletonInner private constructor() {
    companion object {
        val instance = SingletonHolder.holder
    }

    private object SingletonHolder {
        val holder= SingletonInner()
    }
}

总结

以上都是常用的单例定义方式,其实单例的实现还有很多实现的方式,如枚举,容器等,但是都不常用。

由于我们Android客户端并没有太多的并发,多线程等场景,所以大家使用哪一种单例都不会有太大的影响,就像Kotlin推荐使用的object单例一样。

大家只需要注意在多线程中用到单例对象的时候留心即可,是否需要同步锁,可以分不同的场景使用不同的单例定义方式。

注意:
单例模式由于全局只有一个实例,所以如果持有上下文是Activity对象,那么会导致Activity对象无法释放,会造成内存泄露