单例模式
简介
单例设计模式是一种创建型设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点。在单例模式中,类的构造函数是私有的,以防止直接实例化。同时,类会提供一个静态方法,用于获取类的唯一实例。如果实例不存在,则会创建一个新的实例;如果实例已经存在,则返回已有的实例。可以说单例模式属于项目中经常会被考虑用到的一种设计模式。单例模式分为懒汉式、饿汉式。
什么时候考虑用单例模式?| 使用场景
- 唯一性需求、资源共享类应用: 当系统中需要一个类只有一个实例,以协调任务、跟踪全局状态或控制资源访问时,需要确保一些共享的资源时,可以考虑使用单例模式。比如配置管理类应用程序,需要访问全局配置信息,如数据库连接、日志记录器等。使用单例模式可以确保配置信息只被加载和初始化一次,并在整个应用程序中共享,避免资源浪费和冲突。
- 全局访问点: 当希望通过一个全局的访问点访问一个对象,以便集中管理相关的操作时,可以使用单例模式。
- 节省资源: 当创建对象的代价比较大,但又经常需要使用相同的对象时,可以考虑使用单例模式,节省资源。比如缓存管理,缓存是一种存储经常使用或需要大量计算的数据的地方,以减少对原始数据源的访问。使用单例模式可以确保缓存数据在整个应用程序中是唯一和一致的。
- 控制实例数量: 在某些情况下,系统只能容许存在一个实例,如线程池、缓存管理等,这时单例模式是一种很好的选择。线程池是一种用于限制并发线程数量的对象,可以重复利用已存在的线程来执行新的任务。使用单例模式可以确保线程池在整个应用程序中只存在一个实例,并且可以被所有线程安全地访问。
饿汉模式
懒汉模式
对比
懒汉式:
- 实例延迟加载: 懒汉式在第一次使用时才创建实例,也就是说实例的创建被延迟到需要的时候进行。
- 线程不安全: 在多线程环境下,懒汉式可能存在线程安全问题。当多个线程同时访问时,可能会导致创建多个实例,破坏了单例的初衷。
饿汉式
- 实例预先创建: 饿汉式在类加载时就创建实例,不管是否使用,实例都会被创建。
- 线程安全: 由于实例在加载类时就被创建,因此不存在多线程环境下的竞争问题,是线程安全的。
总结
选择懒汉式还是饿汉式,取决于实际需求。如果希望在需要时再创建实例,可以选择懒汉式;如果希望在程序启动时就预先创建实例,可以选择饿汉式。需要注意的是,在多线程环境下,懒汉式需要加入额外的线程安全措施,而饿汉式通常无需担心线程安全问题。