Android开发模式之单例模式

目录

一、单例模式的作用和使用场景

二、五种单例模式

2.1 饿汉模式

2.2 懒汉模式

2.3 双重检查加锁方式

2.4 静态内部类方式

2.5 枚举单例模式

总结


一、单例模式的作用和使用场景

单例模式是设计模式中最常见的的一种设计模式,保证了一个类只有一个实例存在并且能够全局访问到。常见的使用场景有:应用中某个实例对象需要被频繁的访问;应用每次启动都只会存在一个实例,如账号系统、数据库对象(SQLiteOpenHelper)等。

二、五种单例模式

2.1 饿汉模式

public class SingletonStarving {
    //直接初始化静态变量,确保线程安全
    private static final SingletonStarving mInstance= new SingletonStarving();
    private SingletonStarving() {
    }
    public static SingletonStarving getInstance(){
        return mInstance;
    }
}
  • 构造函数使用private修饰,外部无法访问
  • 在声明对象时初始化
  • static关键字修饰静态变量,使内存中只有一份数据
  • final关键字保证只初始化一次

2.2 懒汉模式

public class SingletonSlacker {
    private static SingletonSlacker mInstance;

    private SingletonSlacker() {
    }

    public static synchronized SingletonSlacker getInstance() {
        if (mInstance == null) {
            mInstance = new SingletonSlacker();
        }
        return mInstance;
    }
}
  • 构造函数使用private修饰,外部无法访问
  • 使用的时候要调用getInstance的时候才初始化
  • static关键字修饰,静态变量在内存中只有一份数据
  • synchronized线程安全,在多线程下单例的唯一性
  • 缺点是:每次调用都会getInstance一次

2.3 双重检查加锁方式

public class Singleton {
    //volatile关键字确保多线程下正确处理Singleton 
    private volatile static Singleton mInstance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        //第一次判空
        if (mInstance == null) {
             //进入同步区域
            synchronized (Singleton.class) {  
                //第二次判空
                if (mInstance == null) {
                    mInstance = new Singleton();
                }
            }
        }
        return mInstance;
    }
}
  • 构造函数使用private修饰,外部无法访问
  • 在使用的时候调用getInstance进行初始化
  • static关键字修饰
  • synchronized线程安全,多线程情况下的唯一性
  • 两次判空避免多次同步

2.4 静态内部类方式

public class SingletonInternalClass {
    private SingletonInternalClass() {
    }

    public static SingletonInternalClass getInstance() {
        return SingletonInternalClassHolder.instance;
    }

    private static class SingletonInternalClassHolder {
        private static final SingletonInternalClass instance = new SingletonInternalClass();
    }
}
  • 构造函数使用private修饰外部无法访问
  • 使用的时候调用getInstance进行初始化
  • 调用getInstance才去加载SingletionInternalClassHolder类,确保线程安全。

2.5 枚举单例模式

public class User {

    //私有化构造函数
    private User(){}

    //定义一个静态枚举类
    static enum SingletonEnum{
        //创建一个枚举对象
        INSTANCE;
        private User user;
        //私有化枚举的构造函数
        private SingletonEnum(){
            user = new User();
        }
        public User getInstance(){
            return user;
        }
    }
    //对外暴露一个获取User对象的静态方法
    public static User getInstance(){
        return SingletonEnum.INSTANCE.getInstance();
    }
}

总结

1.饿汉式:类初始化的时候会立即加载该对象,线程安全调用效率高。缺点是造成内存浪费。

2.懒汉式:只有使用的时候才去创建对象,具备懒加载的功能。缺点:线程不安全。

3.双重检查加锁的方式:只在使用时加载,节省资源,缺点:存在线程安全问题

3.静态内部类方式:结合了懒汉模式和饿汉模式的各自优点,需要时加载而且线程安全

4.枚举类型的单例:使用枚举实现单例模式,实现简单调用效率高。枚举本身就是单例,由JVM从根本上提供保障,避免反射和反序列化的漏洞,缺点时没有延迟加载。

参考
https://www.jb51.net/article/97989.htm

总结单例模式的几种实现方式及优缺点_worldchinalee的博客-CSDN博客_枚举单例模式优缺点

猜你喜欢

转载自blog.csdn.net/weixin_43858011/article/details/125150958