详解23种设计模式——单例模式

embedded/2024/10/16 2:31:35/

单例模式 | CoderMast编程桅杆单例模式 单例模式是最常用的设计模式之一,他可以保证在整个应用中,某个类只存在一个实例化对象,即全局使用到该类的只有一个对象,这种模式在需要限制某些类的实例数量时非常有用,通常全局只需要一个该对象即可,如一些配置文件映射对象、数据库连接对象等。 饿汉模式 和 懒汉模式 单例模式根据其实现方式不同,又可以分成两种类型:饿汉模式 和 懒汉模式。 饿汉模式:...icon-default.png?t=N7T8https://www.codermast.com/dev-idea/design-patterns/create-patterns/singleton-pattern.html

单例模式是最常用的设计模式之一,他可以保证在整个应用中,某个类只存在一个实例化对象,即全局使用到该类的只有一个对象,这种模式在需要限制某些类的实例数量时非常有用,通常全局只需要一个该对象即可,如一些配置文件映射对象、数据库连接对象等。

饿汉模式 和 懒汉模式

单例模式根据其实现方式不同,又可以分成两种类型:饿汉模式 和 懒汉模式。

  • 饿汉模式:可以理解为餐馆老板认为每个顾客来到餐馆时都是快要饿死的状态,一旦请求食物,则必须立刻提供给他,必须尽快让他吃到东西,为了达到这样的效果,就必须提前把食物准备好,只等顾客来吃即可。

  • 懒汉模式:可以理解为餐馆老板是一个非常懒的人,没有客人的时候,他什么也不会准备,只有当顾客点餐以后,老板才会开始工作。

设计思想

  1. 日志记录

在应用程序中,通常会有多个模块需要记录日志,为了避免创建多个日志记录器实例,使用单例模式就可以确保只有一个日志记录器实例,从而避免重复记录日志并提高应用程序的性能。

  1. 数据库连接

在应用程序中,需要频繁的和数据库进行交互,使用单例模式可以确保只有一个数据库连接实例,从而减少数据库连接的数量,提高程序的性能,减少资源的消耗。

  1. 配置文件

在应用程序中,通常会有一些全局的配置参数,如数据连接信息、项目配置信息、缓存大小等一些参数,使用单例模式可以确保只有一个配置实例,保证了参数的唯一性,从而方便管理和修改配置参数。

实现案例

饿汉模式

这种模式下,即使当前没有人来请求资源,在类加载的时候就会提前将所需要的资源准备好,只等来拿。

因为是在类加载的阶段初始化的,且类加载在程序的执行过程中仅出现一次,故其是线程安全的。

class SingletonHungry {// static 修饰的,在类加载时就会被初始化private static final SingletonHungry singletonHungry = new SingletonHungry();// 将构造器设为私有的,禁止从外部创建实例private SingletonHungry() {}// 提供获取单例对象的方法public static SingletonHungry getInstance() {return singletonHungry;}
}

懒汉模式

这种模式下,只有当有人来获取资源的时候,才会开始准备资源。因为是需要进行手动初始化,在并发环境下就有可能出现构建了多个实例对象的情况,需要我们手动去处理。

  • 懒汉模式:不考虑并发

class SingletonLazy {// 默认不初始化private static SingletonLazy singletonLazy;// 将构造器设为私有的,禁止从外部创建实例private SingletonLazy() {}// 提供获取单例对象的方法public static SingletonLazy getInstance() {if (singletonLazy == null) {singletonLazy = new SingletonLazy();}return singletonLazy;}
}
  • 懒汉模式:考虑并发

使用双重检查锁它可以在保证线程安全的同时实现延迟加载

class SingletonLazy {// 默认不初始化private static SingletonLazy singletonLazy;// 将构造器设为私有的,禁止从外部创建实例private SingletonLazy() {}// 提供获取单例对象的方法public static SingletonLazy getInstance() {if (singletonLazy == null) {synchronized ( SingletonLazy.class ) {if (singletonLazy == null) {singletonLazy = new SingletonLazy();}}}return singletonLazy;}
}

枚举方式

警告

前面的两种方式中,看似是实现了单例模式,但是 Java 中一些机制可以破坏单例模式,会导致单例对象不唯一,例如反射机制、克隆机制、序列化和反序列化等。那这该如何解决呢?答案是使用 Enum 类来实现。

使用枚举实现单例模式的好处是,可以避免反射和序列化攻击。因为枚举类型的构造函数是私有的,所以无法使用反射来创建实例;而且枚举类型的实例在序列化和反序列化时会自动处理好,所以也无法通过序列化和反序列化来破坏单例。

  • 定义枚举类

public enum SingletonEnum {SINGLETONENUM;public void doSomething() {// TODO:这里可以写一些单例对象的相关行为和操作}
}
  • 使用枚举类

public class SingletonEnumTest {public static void main(String[] args) {SingletonEnum singletonEnum = SingletonEnum.SINGLETON_ENUM;SingletonEnum singletonEnum2 = SingletonEnum.SINGLETON_ENUM;System.out.println(singletonEnum  == singletonEnum2);}
}

输出的结果为 true ,说明这两个是同一个对象。


http://www.ppmy.cn/embedded/17644.html

相关文章

【R语言简介】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

JVM学习笔记(五)内存模型

目录 1、原子性 1.1 问题分析 1.2 解决方法 2、可见性 2.1 退不出的循环 2.2 解决办法 3、有序性 3.1 诡异的结果 3.2 解决办法 3.3 有序性理解 3.4 happens-before 4、CAS与原子类 4.1 CAS 4.2 乐观锁与悲观锁 4.3 原子操作类 5、synchronized 优化 5.1 轻量…

JVM之初识垃圾收集器

JDK 8:Parallel Scavenge(新生代) Parallel Old(老年代)JDK8以后:G1收集器 什么是串行回收和并行回收? Serial收集器:串行收集器 新生代使用标记复制算法,老年代使用标记…

GITEE本地项目上传到远程

由于需要,我这边将本地的仓库上传至GITEE。之前在网上搜索了相关的文档,但是步骤很繁琐,我这边介绍一个非常简单的。 一、在GITEE新建仓库 跟着指引一步步新建。 二、打开本地仓库,删除.git文件 默认情况下不会有这个.git文件&a…

iOS - 多线程-GCD-队列组

文章目录 iOS - 多线程-GCD-队列组1. 队列组1.1 基本使用步骤 iOS - 多线程-GCD-队列组 开发过程中,有时候想实现这样的效果 多个任务并发执行所有任务执行完成后,进行下一步处理(比如回到主线程刷新UI) 1. 队列组 可以使用GC…

Win 进入桌面黑屏,只有鼠标

大家好,我叫秋意零。 今天,遇到一个同事电脑进入桌面黑屏,只有鼠标。经过询问沟通,说是 Windows 突然进行了自动更新,更新之后桌面就黑了屏。经过查询是一个桌面进程没启动才会导致桌面黑屏。首先分两种情况&#xff0…

K8S 哲学 - yaml文件

selector: Pod 对象不应该有 selector 字段。selector 字段通常用于 Service、Deployment、ReplicaSet 等对象,用于选择匹配的 Pod。在 Pod 对象中,这个字段是无效的 apiVersion: apps/v1 kind: Deployment metadata: name: gyk labels: …

llama3本地部署

目录 II.下载 II.验证ollama安装 II.安装llama3 和启动 II.命令行调用 II.api调用 II.参考文献 II.下载 https://ollama.com/download/windows OllamaSetup.exe https://github.com/meta-llama/llama3 II.验证ollama安装 cmd ollama II.安装llama3 和启动 ollama run …