1. 单例模式的实现方式及线程安全

单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点。以下是常见的单例模式实现方式,以及如何保证线程安全:

单例模式的实现方式
  1. 饿汉式(Eager Initialization)

    • 实现:在类加载时就创建实例(静态初始化)。

    • 代码示例

      public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}}
      
    • 线程安全:天生线程安全,因为实例在类加载时创建,JVM保证类加载过程是线程安全的。

    • 优缺点:简单,但可能会导致资源浪费(如果实例未被使用)。

  2. 懒汉式(Lazy Initialization)

    • 实现:在第一次调用时创建实例。

    • 代码示例(非线程安全)

      public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}
      
    • 线程安全问题:多线程环境下,可能多个线程同时判断instance == null,导致多次创建实例。

    • 改进(加锁)

      public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
      }
      
      • 使用synchronized关键字保证线程安全,但锁粒度较大,性能较低。
  3. 双重检查锁(Double-Checked Locking)

    • 实现:在懒汉式基础上优化,使用双重检查和volatile关键字。

    • 代码示例

      收起自动换行

      public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
      }
      
    • 线程安全:volatile防止指令重排序,确保实例初始化完成前其他线程不会访问;双重检查减少锁的开销。

    • 优缺点:性能较高,但代码稍复杂。

  4. 静态内部类(Static Inner Class)

    • 实现:利用静态内部类的延迟加载特性。

    • 代码示例

      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时才加载SingletonHolder,实现懒加载。

    • 优缺点:兼顾懒加载和线程安全,推荐使用。

  5. 枚举单例(Enum Singleton)

    • 实现:利用Java枚举类型的特性。

    • 代码示例

      public enum Singleton {INSTANCE;public void doSomething() {// 业务逻辑}}
      
    • 线程安全:JVM保证枚举的实例化是线程安全的,且能防止反射和序列化破坏单例。

    • 优缺点:简洁、安全,但不适合复杂的初始化逻辑。

保证线程安全的关键点
  • 饿汉式和枚举:天生线程安全,依赖JVM类加载机制。

  • 懒汉式:需加锁(如synchronized)或使用双重检查锁。

  • 双重检查锁:结合volatile和synchronized,防止指令重排序和多线程竞争。

  • 静态内部类:利用JVM类加载机制,延迟加载且线程安全。

  • 序列化和反射攻击

    • 防止反射:构造函数抛出异常或使用枚举。

    • 防止序列化破坏:在类中添加

      readResolve

   private Object readResolve() {return instance;

2. 策略模式(Strategy Pattern)

定义

策略模式是一种行为型设计模式,定义一系列算法(策略),将每个算法封装起来,并使它们可以互换。客户端可以根据需要选择不同的策略,而不改变调用代码。

核心组成
  • 抽象策略接口(Strategy):定义算法的接口。
  • 具体策略类(ConcreteStrategy):实现具体算法。
  • 上下文类(Context):持有策略接口的引用,负责调用具体策略。
代码示例
// 策略接口interface Strategy {int execute(int a, int b);
}// 具体策略:加法
class AddStrategy implements Strategy {@Overridepublic int execute(int a, int b) {return a + b;}
}// 具体策略:减法class SubtractStrategy implements Strategy {@Overridepublic int execute(int a, int b) {return a - b;}
}// 上下文class Context {private Strategy strategy;public void setStrategy(Strategy strategy) {this.strategy = strategy;}public int executeStrategy(int a, int b) {return strategy.execute(a, b);}
}// 使用public class Main {public static void main(String[] args) {Context context = new Context();context.setStrategy(new AddStrategy());System.out.println(context.executeStrategy(5, 3)); // 输出 8context.setStrategy(new SubtractStrategy());System.out.println(context.executeStrategy(5, 3)); // 输出 2}}
使用场景
  • 多种算法或行为:当一个类有多种行为,且这些行为可以根据上下文动态切换时(如支付方式:微信、支付宝、银行卡)。

  • 避免条件语句:替代大量if-else或switch语句,使代码更清晰。

  • 算法独立性:需要将算法与客户端代码解耦,方便扩展和维护。

  • 典型案例

    • 排序算法选择(如快速排序、归并排序)。
    • 支付系统(不同支付方式)。
    • 游戏中的角色技能(不同技能效果)。
优缺点
  • 优点:灵活、可扩展,符合开闭原则;代码复用性高。
  • 缺点:客户端需要了解所有策略;策略类可能较多。

3. 模板方法模式(Template Method Pattern)

定义

模板方法模式是一种行为型设计模式,定义一个操作的算法骨架,将某些步骤延迟到子类实现。父类控制算法流程,子类提供具体实现。

核心组成
  • 抽象模板类(AbstractClass):定义算法骨架(模板方法)和抽象方法。
  • 具体子类(ConcreteClass):实现抽象方法,提供具体逻辑。
代码示例
// 抽象模板类abstract class AbstractClass {// 模板方法,定义算法骨架public final void templateMethod() {step1();step2();step3();}protected abstract void step1();protected abstract void step2();protected void step3() { // 可选的钩子方法 也就是子类可以选择性进行重写,不重写默认执行父类方法System.out.println("Default step3");}
}// 具体子类class ConcreteClass extends AbstractClass {@Overrideprotected void step1() {System.out.println("ConcreteClass: Step 1");}@Overrideprotected void step2() {System.out.println("ConcreteClass: Step 2");}@Overrideprotected void step3() {System.out.println("ConcreteClass: Custom Step 3");}
}// 使用public class Main {public static void main(String[] args) {AbstractClass process = new ConcreteClass();process.templateMethod();}}
使用场景
  • 固定算法骨架:当多个类共享相同的算法流程,但部分步骤的实现不同(如数据处理流程:读取、处理、保存)。

  • 代码复用:通过父类定义公共逻辑,子类只实现差异化部分。

  • 控制子类扩展:通过final模板方法限制子类修改算法结构。

  • 典型案例

    • 框架中的生命周期方法(如Spring的ApplicationContext初始化)。
    • 游戏开发中关卡流程(加载、运行、结束)。
    • 报表生成(数据采集、格式化、输出)。
优缺点
  • 优点:提高代码复用性;算法结构统一,易于维护;符合开闭原则。

  • 缺点:子类数量可能增多;父类设计复杂时可能限制灵活性。

  • 使用场景适合抽象类适合接口
    需要代码复用✅ 适合,支持方法和成员变量实现❌ 不适合(除非 default 方法)
    表示“是什么”(is-a)✅ 抽象类适合建层次结构❌ 接口更适合“能做什么”
    表示“能做什么”(has ability to)✅ 非常适合,比如 Serializable, Runnable
    要求多个类共享部分逻辑✅ 用抽象类抽取通用部分❌ 接口不适合写逻辑实现
    实现多个类型/能力组合❌ 不能多继承✅ 接口天生支持多继承

总结对比

  • 单例模式:确保单一实例,关注对象创建,需考虑线程安全(如双重检查锁、静态内部类)。
  • 策略模式:关注行为切换,适合动态选择算法,解耦客户端与算法实现。
  • 模板方法模式:关注算法骨架,适合固定流程但细节可变,强调继承和复用。

拓展:责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,用于将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求。该模式将处理请求的对象组成一条链,请求沿着这条链传递,直到被某个对象处理为止。

结构图(类图)

Client --> Handler1 --> Handler2 --> Handler3 --> …
核心类图包括:

Handler(抽象处理者)

定义处理请求的接口。

持有下一个处理者的引用。

ConcreteHandler(具体处理者)

实现请求处理的逻辑。

如果自己不能处理,则将请求转发给下一个处理者。

Client(客户端)

创建处理链,并将请求传入第一个处理者。

** 应用场景
审批流程(如:员工请假、软件发布等)**

Java Web 的 Filter 过滤器链

Spring Security 的认证授权链

Netty 的 ChannelPipeline

🧑‍💻 Java 示例(审批流程)
比如一个请假流程,组长可以审批 1 天,经理可以审批 3 天,总监可以审批 7 天:

抽象处理者


```java
public abstract class LeaveHandler {protected LeaveHandler next;public void setNext(LeaveHandler next) {this.next = next;}public abstract void handleRequest(int days);
}

具体处理者

public class TeamLeader extends LeaveHandler {@Overridepublic void handleRequest(int days) {if (days <= 1) {System.out.println("组长审批了 " + days + " 天的假期");} else if (next != null) {next.handleRequest(days);}}
}public class Manager extends LeaveHandler {@Overridepublic void handleRequest(int days) {if (days <= 3) {System.out.println("经理审批了 " + days + " 天的假期");} else if (next != null) {next.handleRequest(days);}}
}public class Director extends LeaveHandler {@Overridepublic void handleRequest(int days) {if (days <= 7) {System.out.println("总监审批了 " + days + " 天的假期");} else {System.out.println("假期太长,不批准");}}
}

客户端调用

public class Client {public static void main(String[] args) {LeaveHandler teamLeader = new TeamLeader();LeaveHandler manager = new Manager();LeaveHandler director = new Director();teamLeader.setNext(manager);manager.setNext(director);teamLeader.handleRequest(2); // 输出:经理审批了 2 天的假期teamLeader.handleRequest(6); // 输出:总监审批了 6 天的假期teamLeader.handleRequest(10); // 输出:假期太长,不批准}
}

1.责任链模式的优点?
解耦请求发送者和接收者。
动态调整处理链,灵活性高。
单一职责,每个处理者专注特定请求。
2.缺点?
请求可能未被处理。
链过长影响性能。
调试复杂。

3.使用场景?
日志系统(如不同级别日志处理)。
事件处理(如 GUI 事件传递)。
审批流程(如逐级审批)。

4.如何避免请求未被处理?
设置默认处理者。
确保链配置完整。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/92136.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/92136.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/92136.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis 缓存三大核心问题:穿透、击穿与雪崩的深度解析

引言在现代互联网架构中&#xff0c;缓存是提升系统性能、降低数据库压力的核心手段之一。而 Redis 作为高性能的内存数据库&#xff0c;凭借其丰富的数据结构、灵活的配置选项以及高效的网络模型&#xff0c;已经成为缓存领域的首选工具。本文将从 Redis 的基本原理出发&#…

耘瞳科技国产化点云处理软件,开启智能化三维测量新时代

在现代工业制造领域&#xff0c;三维点云数据已成为推动生产效率提升、质量控制优化以及智能制造转型的关键技术之一。三维点云数据能够提供高精度的物体表面信息&#xff0c;广泛应用于制造零件的质量检测&#xff1b;通过点云数据与CAD模型的对比分析&#xff0c;可以快速检测…

RabbitMQ面试精讲 Day 8:死信队列与延迟队列实现

【RabbitMQ面试精讲 Day 8】死信队列与延迟队列实现 文章标签 RabbitMQ,消息队列,死信队列,延迟队列,面试技巧,分布式系统 文章简述 本文是"RabbitMQ面试精讲"系列第8天&#xff0c;深入讲解死信队列与延迟队列的实现原理与实战应用。文章详细解析死信队列的触发…

团结引擎 1.5.0 版本发布:Android App View 功能详解

核心亮点 原生安卓应用支持 2D & 3D 双形态呈现 编辑器全流程集成 灵活调控功能 多应用并行展示 智能座舱应用示例 快速入门指南 开发说明 功能支持 实验性功能 资源链接 团结引擎 1.5.0 版本已于 4 月 14 日正式上线。本次更新中&#xff0c;车机版引入了一项突…

基于SpringBoot的OA办公系统的设计与实现

文章目录前言详细视频演示具体实现截图后端框架SpringBoot持久层框架MyBaits成功系统案例&#xff1a;代码参考数据库源码获取前言 博主介绍:CSDN特邀作者、985高校计算机专业毕业、现任某互联网大厂高级全栈开发工程师、Gitee/掘金/华为云/阿里云/GitHub等平台持续输出高质量…

知识随记-----用 Qt 打造优雅的密码输入框:添加右侧眼睛图标切换显示

Qt 技巧&#xff1a;通过 QLineEdit 右侧眼睛图标实现密码可见性切换 文章目录Qt 技巧&#xff1a;通过 QLineEdit 右侧眼睛图标实现密码可见性切换概要整体架构流程技术名词解释技术细节实现效果展示概要 本文介绍如何使用 Qt 框架为 QLineEdit 控件添加一个右侧的眼睛图标&a…

Unity里的对象旋转数值跳转问题的原理与解决方案

文章目录1. 问题描述2. 问题原因3. 解决方案3.1通过多个父子关系从而控制旋转&#xff08;推荐&#xff09;3.2 使用四元数进行旋转1. 问题描述 我们现在写一个3D的Unity程序&#xff0c;我们现在设置了一个物体后&#xff0c;我们想旋转使其改为我们想要的情况。但是我们如果…

为什么现代 C++ (C++11 及以后) 推荐使用 constexpr和模板 (Templates) 作为宏 (#define) 的替代品?​

我们用现实世界的比喻来深入理解​​为什么 C 中的宏 (#define) 要谨慎使用&#xff0c;以及为什么现代 C (C11 及以后) 推荐使用 constexpr 和模板 (Templates) 作为替代品。​​&#x1f9e9; ​​核心问题&#xff1a;宏 (#define) 是文本替换​​想象宏是一个 ​​“无脑的…

PyCharm vs. VSCode 到底哪个更好用

在 Python 开发者中&#xff0c;关于 PyCharm 和 VSCode 的讨论从未停止。一个是功能齐备的集成开发环境&#xff08;IDE&#xff09;&#xff0c;另一个是轻快灵活的代码编辑器。它们代表了两种不同的开发哲学&#xff0c;选择哪个&#xff0c;往往取决于你的项目需求、个人习…

FPGA学习笔记——VGA彩条显示

目录 一、任务 二、分析 三、代码 四、实验现象 五、更新 一、任务 使用VGA实现彩条显示&#xff0c;模式是640x48060。 二、分析 首先&#xff0c;模式是640x48060&#xff0c;那么对照以下图标&#xff0c;知道其它信息&#xff0c;不清楚时序和VGA扫描方式的可以看看这…

ES-301A :让 Modbus 设备无缝接入工业以太网的高效桥梁

在工业自动化领域&#xff0c;串口设备与以太网的互联互通是提升系统效率的关键。ES-301A 工业以太网串口网关作为上海泗博自动化精心打造的专业解决方案&#xff0c;以强大的协议转换能力、工业级可靠性和灵活配置特性&#xff0c;成为连接 Modbus RTU/ASCII 设备与 Modbus TC…

【学习笔记】FTP库函数学习

【学习笔记】FTP库函数学习 FTP基本指令步骤 1、初始化会话句柄&#xff1a;CURL *curl curl_easy_init(); 2、设置会话选项&#xff1a; 设置服务器地址&#xff0c;设置登录用户和密码 curl_easy_setopt(curl, CURLOPT_URL, ftp_server); curl_easy_setopt(curl, CURLOPT_US…

ARM Cortex-M异常处理高级特性详解

1. 异常处理概述 ARM Cortex-M处理器提供了高效的异常处理机制&#xff0c;包含多种硬件优化特性&#xff0c;显著提升了中断响应性能和系统效率。这些特性对于实时嵌入式系统和网络协议栈&#xff08;如LwIP&#xff09;的性能至关重要。 1.1 Cortex-M异常处理架构 Cortex-M异…

【图像算法 - 08】基于 YOLO11 的抽烟检测系统(包含环境搭建 + 数据集处理 + 模型训练 + 效果对比 + 调参技巧)

一、项目背景与需求 【打怪升级 - 08】基于 YOLO11 的抽烟检测系统&#xff08;包含环境搭建 数据集处理 模型训练 效果对比 调参技巧&#xff09;今天我们使用YOLO11来训练一个抽烟检测系统&#xff0c;基于YOLO11的抽烟检测系统。我们使用了大概两万张图片的数据集训练了…

vue2升级vue3中v-model的写法改造

vue2选项式 <template><div><el-rowclass"group-title":title"$t(restore_default_parameters)">{{ $t(restore_default_parameters) }}</el-row><el-form-item :label"$t(restore_default_parameters)" class"…

5G-LEO 简介

1. 什么是 5G-LEO 5G-LEO 指的是将 5G 新空口&#xff08;5G NR&#xff09;服务扩展到低轨卫星&#xff08;LEO&#xff09;上的非地面网络&#xff08;NTN, Non-Terrestrial Network&#xff09;方案。通过在距地面约500–2 000 km 的低轨道卫星上部署通信载荷&#xff0c;5G…

【MCAL】AUTOSAR架构下SPI数据同步收发具体实现

目录 前言 正文 1.依赖的SPI硬件特性 1.1. SPI时隙参数配置 1.2. SPI数据发送和接收模式 2.MCAL中的SPI配置 3.软件的具体实现 3.1. Spi_SyncTransmit 3.2. Spi_lSyncTransmit 3.3. Spi_lSyncStartJob 3.4. Spi_lSyncTransmitData8Bit 3.5. Spi_lSynTransErrCheck …

SQL157 更新记录(一)

描述现有一张试卷信息表examination_info&#xff0c;表结构如下图所示&#xff1a;FiledTypeNullKeyExtraDefaultCommentidint(11)NOPRIauto_increment(NULL)自增IDexam_idint(11)NOUNI(NULL)试卷IDtagchar(32)YES(NULL)类别标签difficultychar(8)YES(NULL)难度durationint(11…

悬赏任务系统小程序/APP源码,推荐任务/发布任务/会员服务

1. 我们承诺及优势本店源码承诺&#xff1a;1&#xff09;. 店长亲测 - 100%完整可运行2&#xff09;. 含详细安装文档3&#xff09;. 支持二次开发定制4&#xff09;. 专业客服随时解答5&#xff09;. 技术团队保障质量2. 功能详细说明主要功能 模块 角色 解释说明 用户登录和…

Ubuntu20.04系统上使用YOLOv5训练自己的模型-1

在Ubuntu系统上使用YOLOv5训练自己的模型&#xff0c;你需要遵循以下步骤。这里我将详细说明如何从准备数据集到训练模型的整个过程。 步骤 1: 安装依赖项 首先&#xff0c;确保你的Ubuntu系统上安装了Python、PyTorch和必要的库。你可以使用以下命令安装这些依赖项&#xff1a…