Android编程设计模式之单例模式实例详解
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点,在Android开发中,单例模式广泛应用于资源管理、工具类以及需要频繁创建和销毁的类中,本文将详细介绍单例模式的定义、使用场景、实现方式及其优缺点,并通过实例进行说明。
一、定义与使用场景
1. 定义:
单例模式的核心在于保证一个类只有一个实例存在,并提供一个全局访问点,这意味着无论何时何地,只要调用该类的静态方法getInstance()
,返回的都是同一个对象。
2. 使用场景:
资源管理:如数据库连接池、线程池等,避免频繁创建和销毁带来的性能开销。
配置信息:如读取配置文件的场景,只需一次读取即可多次使用。
日志服务:确保日志文件的统一管理,避免多份日志造成的混乱。
工具类对象:如字符串处理、IO操作等工具类,不需要多个实例。
二、实现方式及优缺点
1. 饿汉式(Eager Initialization)
示例代码:
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
优点:
实现简单,线程安全。
类加载时就完成实例化,避免线程同步问题。
缺点:
类加载时就初始化,不管是否使用该实例,可能会造成资源浪费。
2. 懒汉式(Lazy Initialization)
示例代码:
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
优点:
延迟加载,需要时才创建实例,节约资源。
缺点:
每次调用getInstance()
都需要进行同步判断,影响性能。
3. 双重检查锁定(Double Check Lock, DCL)
示例代码:
public class Singleton { private volatile static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
优点:
延迟加载,资源利用率高。
线程安全,只在第一次实例化时同步,之后不再同步。
缺点:
实现相对复杂。
在JDK1.5之前可能会有失效的情况,需加入volatile
关键字解决。
4. 静态内部类方式
示例代码:
public class Singleton { private Singleton() {} private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
优点:
延迟加载,资源利用率高。
线程安全,由JVM保证静态内部类的线程安全。
缺点:
实现稍显复杂。
饿汉式:
适用于希望在类加载时就完成实例化的场景,如某些必须提前初始化的工具类或配置类,其简单性和线程安全性使其在某些情况下非常实用,如果实例化过程较为耗时或耗资源,这种方式可能会导致不必要的性能开销。
懒汉式:
适用于实例化过程较为耗时且不希望提前初始化的场景,通过同步方法确保线程安全,但每次调用getInstance()
都需要进行同步判断,这在一定程度上影响了性能,在对性能要求较高的系统中,应谨慎使用。
双重检查锁定(DCL):
结合了懒汉式的优点并避免了其缺点,通过两次判空和同步块的使用,实现了延迟加载和线程安全,由于实现相对复杂且在JDK1.5之前可能存在失效情况,因此在实际应用中需要谨慎考虑。
静态内部类方式:
推荐使用的一种实现方式,它既实现了延迟加载又保证了线程安全,且由JVM自动处理同步问题,简化了代码实现,在Android开发中,许多开源项目如Universal-Image-Loader等都采用了这种方式。
四、相关问题与解答
问1:为什么饿汉式单例模式不能实现懒加载?
答1:饿汉式单例模式在类加载时就完成了实例化,无论是否使用该实例都会进行初始化,而懒加载是指在实际需要时才进行初始化,以节约资源,饿汉式单例模式无法实现懒加载。
问2:双重检查锁定(DCL)中的“volatile”关键字起什么作用?
答2:在DCL单例模式中,volatile
关键字的作用是防止指令重排导致的线程安全问题,它确保了当一个线程在检查instance
是否为null
时,如果有另一个线程正在初始化instance
,那么这个线程必须等待初始化完成后才能继续执行,这样可以避免多个线程同时创建多个实例的问题。
到此,以上就是小编对于“Android编程设计模式之单例模式实例详解”的问题就介绍到这了,希望介绍的几点解答对大家有用,有任何问题和不懂的,欢迎各位朋友在评论区讨论,给我留言。
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/638438.html