在安卓中使用最频繁的设计模式就是单例模式,例如工具类等等。
单例模式(Singleton Pattern) ,属于创建型模式。这种模式创建自己这个对象,并保证只有一个对象。
懒汉式
懒汉式单例模式,创建流程是先判断该对象有无创建过,若没有创建过,在实例化前再判断一回,并加锁,避免同时创建多个对象,这样就可以保证只有一个对象被创建了。编译器(JIT),CPU有可能对指令进行重排序,导致使用到尚未初始化的实例,可以通过添加volatile关键字进行修饰,可以防止指令重排。
优点:第一次初始化后就不需要再创建对象(单一对象),后续使用都不需要再创建,可以避免内存泄露,且线程安全,双重判断是否为空可以优化加锁。
缺点:由于加锁操作可能导致效率低下。
public class LazySingleton {
//volatile防止指令重排
private volatile static LazySingleton instance;
//构建方法
public LazySingleton() {
}
//1.判断instance是否为空
//2.synchronized加锁
//3.若instance为空,则创建对象
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
//对外方法,用于测试,功能是打印数据
public void showMessage() {
System.out.println("Hello LazySingleton!");
}
}
饿汉式
饿汉式单例模式,创建流程是在类中直接创建对象,开放方法获取对象。
优点:执行速度快。
缺点:类加载时就初始化,浪费内存,易产生垃圾。
public class HungrySingleton {
//实例化
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
//返回对象
public static HungrySingleton getInstance() {
return instance;
}
//对外方法,用于测试,功能是打印数据
public void showMessage() {
System.out.println("Hello HungrySingleton!");
}
}
登记式
登记式单例模式也称为内部静态类单例模式。创建流程是有一个内部类,外部类在调用getInstance()时,再去调用内部类实例化对象。本质上是利用类的加载机制来保证线程安全,只有在实际使用的时候,才会触发类的初始化,所以也是懒加载的一种形式。
优点:双检锁,避免浪费内存,且线程安全。
public class InnerClassSingleton {
//内部的对象
private static class InnerClassHolder {
private static InnerClassSingleton instance = new InnerClassSingleton();
}
//构建方法
public InnerClassSingleton() {
}
//返回对象
public static InnerClassSingleton getInstance() {
return InnerClassHolder.instance;
}
//对外方法,用于测试,功能是打印数据
public void showMessage() {
System.out.println("Hello InnerClassSingleton!");
}
}
枚举式
枚举式单例模式,对象用enum修饰,天然不支持反射创建对应的实例,且有自己的反序列化机制,利用类加载机制保证线程安全。
public enum EnumSingleton {
INSTANCE;
//对外方法,用于测试,功能是打印数据
public void showMessage() {
System.out.println("Hello EnumSingleton!");
}
}