二.单例模式‌

news2025/6/8 7:24:52

一.单例模式的定义

单例模式是一种‌创建型设计模式‌,确保一个类‌只有一个实例‌,并提供该实例的‌全局访问点‌。

1.1.核心目标

  • 唯一实例‌:限制类的实例化次数仅一次。
  • 全局访问‌:提供统一的访问入口(通常是静态方法)。

1.2.实现步骤

  • 私有化构造函数‌:禁止外部通过new创建实例。
  • 静态私有成员‌:保存类的唯一实例。
  • 静态公有方法‌:提供全局访问入口,如getInstance()

.1.3.优点

  • 资源共享‌:如数据库连接池、线程池、配置文件管理器等全局资源。
  • 状态一致性‌:避免多个实例导致状态冲突(如计数器)。
  • 性能优化‌:减少重复创建昂贵对象的开销

二.单例模式的实现方式

2.1.饿汉式实现

  • 特点:类加载时立即创建实例(线程安全)。
  • 优点‌:简单高效,无同步开销。
  • 缺点‌:可能造成资源浪费(即使未使用也会创建实例)。
/**
 * 饿汉式单例
 */
public class EagerSingleton {
    // 创建一个静态的实例,静态常量,在类加载的时候创建实例
    private static final EagerSingleton instance = new EagerSingleton();
    // 私有化构造方法,使的用者无法通过new关键字创建对象
    private EagerSingleton() {
    }
    //  提供获取实例的方法
    public static EagerSingleton getInstance() {
        return instance;
    }
}

public class demo {
    public static void main(String[] args) {
        EagerSingleton instance = EagerSingleton.getInstance();
        EagerSingleton instance2 = EagerSingleton.getInstance();
        System.out.println(instance == instance2); // true
    }
}

2.2.懒汉式实现

  • 特点‌:延迟实例化(首次调用getInstance()时创建)。
  • 优点‌:首次创建后不再同步,兼顾性能与安全。
  • 注意‌:必须使用volatile关键字(避免JVM指令重排序导致未初始化完全的错误实例)。
/**
 * 懒汉式单例普通实现
 */
public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {
    }

    /**
     * 在多线程环境下,多个线程可能同时进入 if (instance == null) 条件块,
     * 并且每个线程都可能执行 new LazySingleton() 语句,从而导致创建多个实例
     * @return
     */
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton(); // 这里可能会有并发问题
        }
        return instance;
    }
}

/**
 * 懒汉式单例‌双重检查锁定实现
 */
public class LazySingleton {
    // volatile 关键字是为了避免指令重排
    private static volatile LazySingleton instance;

    private LazySingleton() {
    }

    /**
     * 在多线程环境下,多个线程可能同时进入 if (instance == null) 条件块,
     * 并且每个线程都可能执行 new LazySingleton() 语句,从而导致创建多个实例
     * 所以需要使用 synchronized 关键字修饰 getInstance() 方法,
     * @return
     */
    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized(LazySingleton.class){
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

2.3.静态内部类实现

  • 特点‌:利用类加载机制保证线程安全,延迟加载。
  • 优势‌:线程安全(JVM保证类加载过程的互斥性)。无同步开销,高效延迟加载。
/**
 * 静态内部类实现单例模式
 */
public class HolderSingleton {
    private HolderSingleton() {
    }

    /**
     * JVM 确保一个类只会被初始化一次,即使多个线程同时尝试加载该类。
     * 当 HolderSingleton 类被加载时,其内部的 Holder 类并不会立即被加载
     */
    private static class Holder {
        private static final HolderSingleton INSTANCE = new HolderSingleton();
    }

    /**
     * 延迟加载
     * 只有当调用 getInstance() 方法时,才会触发 Holder.INSTANCE 的访问
     * 此时 JVM 才会加载并初始化 Holder 类,并创建 HolderSingleton 实例
     * @return
     */
    public static HolderSingleton getInstance() {
        return Holder.INSTANCE;
    }
}

2.4.枚举实现

  • 特点‌:天然防反射/序列化破坏,简洁安全。
  • 调用方式‌:Singleton.INSTANCE.doSomething()
  • 优势‌:绝对单例(JVM保障)。自动处理序列化和反射攻击。
/**
 * 枚举单例模式
 */
public enum  EnumSingleton {
    //
    /**
     * 枚举实例由JVM在类加载时静态初始化,保证线程安全
     * Java规范禁止通过反射创建枚举实例,避免传统单例被反射攻击的问题
     * 枚举的序列化机制仅保存枚举名称,反序列化时通过valueOf还原原实例,防止生成新对象
     */
    INSTANCE; // 唯一实例

    /**
     *实例方法
     */
    public void whateverMethod() {
        System.out.println("whateverMethod");
    }
}

public static void main(String[] args) {
        //调用
        EnumSingleton.INSTANCE.whateverMethod();
    }

三.应用场景

3.1.初始化开销

  •  ‌轻量级对象‌(CPU耗时<50ms,内存<1MB):
    • 适用场景‌:配置管理器、工具类(如字符串处理器)16
    • 饿汉式‌:实例在类加载时创建,启动速度快
  • 重量级对象‌(数据库连接、大型缓存):
    • 适用场景‌:数据库连接池、日志系统
    • 静态内部类/DCL‌:延迟加载,避免启动阻塞

3.2.线程安全

  • 高并发场景‌:
    • 双重检查锁(DCL)‌:通过volatile+同步块确保安全(如支付网关)36
    • 枚举‌:JVM保障线程安全(如金融交易引擎)512
  • 低并发场景‌:
    • 静态内部类‌:无锁延迟加载(如配置文件读取器)

3.3.防破坏需求

  • 枚举‌:Java规范禁止反射创建枚举实例

3.4.场景化推荐

场景推荐模式原因
‌全局配置管理器‌饿汉式配置轻量且启动必用
‌数据库连接池‌静态内部类延迟加载避免启动卡顿,无锁线程安全
‌金融交易核心‌枚举防反射攻击,强一致性要求
‌高频工具类‌饿汉式无状态对象,快速访问
‌第三方服务代理‌双重检查锁(DCL)按需加载+高并发安全(如支付网关)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零开始开发纯血鸿蒙应用之网络检测

从零开始开发纯血鸿蒙应用 〇、前言一、认识 connection 模块1、获取默认网络2、获取网络能力信息3、解析网络能力信息3.1、NetCap3.2、NetBearType 二、实现网络检测功能1、申请权限2、获取默认网路的 NetCap 数组 三、总结 〇、前言 在之前的博文里&#xff0c;介绍了如何实…

向 AI Search 迈进,腾讯云 ES 自研 v-pack 向量增强插件揭秘

作者&#xff1a;来自腾讯云刘忠奇 2025 年 1 月&#xff0c;腾讯云 ES 团队上线了 Elasticsearch 8.16.1 AI 搜索增强版&#xff0c;此发布版本重点提升了向量搜索、混合搜索的能力&#xff0c;为 RAG 类的 AI Search 场景保驾护航。除了紧跟 ES 官方在向量搜索上的大幅优化动…

【win | docker开启远程配置】使用 SSH 隧道访问 Docker的前操作

在主机A pycharm如何连接远程主机B win docker? 需要win docker配置什么&#xff1f; 快捷配置-主机B win OpenSSH SSH Server https://blog.csdn.net/z164470/article/details/121683333 winR,打开命令行&#xff0c;输入net start sshd,启动SSH。 或者右击我的电脑&#…

股指期货波动一个点多少钱?

很多朋友在交易股指期货时&#xff0c;都会好奇一个问题&#xff1a;股指期货波动一个点&#xff0c;我的账户里到底是赚了还是亏了多少钱&#xff1f;要搞清楚这个问题&#xff0c;其实很简单&#xff0c;只需要了解两个关键信息&#xff1a;股指期货的“交易单位”&#xff0…

iOS、Android、鸿蒙、Web、桌面 多端开发框架Kotlin Multiplatform

Kotlin Multiplatform&#xff08;简称 KMP&#xff09;是 JetBrains 推出的开源跨平台开发框架 Kuikly 是腾讯开源的跨端开发框架&#xff0c;基于 Kotlin Multiplatform 技术构建&#xff0c;为开发者提供了技术栈更统一的跨端开发体验 KMP 不仅局限于移动端&#xff0c;它…

探索C++标准模板库(STL):String接口的底层实现(下篇)

前引&#xff1a;在C的面向对象编程中&#xff0c;对象模型是理解语言行为的核心。无论是类的成员函数如何访问数据&#xff0c;还是资源管理如何自动化&#xff0c;其底层机制均围绕两个关键概念展开&#xff1a;this指针与六大默认成员函数。它们如同对象的“隐形守护者”&am…

Flutter知识点汇总

Flutter架构解析 1. Flutter 是什么?它与其他移动开发框架有什么不同? Flutter 是 Google 开发的开源移动应用开发框架,可用于快速构建高性能、高保真的移动应用(iOS 和 Android),也支持 Web、桌面和嵌入式设备。。它与其他移动开发框架(如 React Native、Xamarin、原…

​线性注意力 vs. 传统注意力:效率与表达的博弈新解

​核心结论​&#xff1a;线性注意力用计算复杂度降维换取全局建模能力&#xff0c;通过核函数和结构优化补足表达缺陷 一、本质差异&#xff1a;两种注意力如何工作&#xff1f; ​特性​传统注意力&#xff08;Softmax Attention&#xff09;线性注意力&#xff08;Linear At…

YOLO在QT中的完整训练、验证与部署方案

以下是YOLO在QT中的完整训练、验证与部署方案&#xff1a; 训练方案 准备数据集&#xff1a; 收集数据&#xff1a;收集与目标检测任务相关的图像数据集&#xff0c;可以是公开数据集如COCO、Pascal VOC&#xff0c;也可以是自定义数据集。标注数据&#xff1a;使用标注工具如…

增量式网络爬虫通用模板

之前做过一个项目&#xff0c;他要求是只爬取新产生的或者已经更新的页面&#xff0c;避免重复爬取未变化的页面&#xff0c;从而节省资源和时间。这里我需要设计一个增量式网络爬虫的通用模板。可以继承该类并重写部分方法以实现特定的解析和数据处理逻辑。这样可以更好的节约…

【JVM】三色标记法原理

在JVM中&#xff0c;三色标记法是GC过程中对象状态的判断依据&#xff0c;回收前给对象设置上不同的三种颜色&#xff0c;三色分为白色、灰色、黑色。根据颜色的不同&#xff0c;决定对象是否要被回收。 白色表示&#xff1a; 初始状态&#xff1a;所有对象未被 GC 访问。含义…

【uniapp开发】picker组件的使用

项目uniapp&#xff0c;结合fastadmin后端开发 picker组件的官方文档说明 https://en.uniapp.dcloud.io/component/picker.html#普通选择器 先看效果&#xff1a; 1、实现设备类型的筛选&#xff1b;2、实现设备状态的筛选&#xff1b; 前端代码&#xff08;节选&#xff0…

【HarmonyOS Next之旅】DevEco Studio使用指南(三十一) -> 同步云端代码至DevEco Studio工程

目录 1 -> 同步云函数/云对象 1.1 -> 同步单个云函数/云对象 1.2 -> 批量同步云函数/云对象 2 -> 同步云数据库 2.1 -> 同步单个对象类型 2.2 -> 批量同步对象类型 3 -> 一键同步云侧代码 1 -> 同步云函数/云对象 说明 对于使用DevEco Studio…

go-zero微服务入门案例

一、go-zero微服务环境安装 1、go-zero脚手架的安装 go install github.com/zeromicro/go-zero/tools/goctllatest2、etcd的安装下载地址根据自己电脑操作系统下载对应的版本&#xff0c;具体的使用自己查阅文章 二、创建一个user-rpc服务 1、定义user.proto文件 syntax &qu…

Python控制台输出彩色字体指南

在Python开发中&#xff0c;有时我们需要在控制台输出彩色文本以提高可读性或创建更友好的用户界面。本文将介绍如何使用colorama库来实现这一功能。 为什么需要彩色输出&#xff1f; 提高可读性&#xff1a;重要信息可以用不同颜色突出显示更好的用户体验&#xff1a;错误信息…

开源之夏·西安电子科技大学站精彩回顾:OpenTiny开源技术下沉校园,点燃高校开发者技术热情

开源之夏2025编程活动正在如火如荼的进行中&#xff0c;当前也迎来了报名的倒计时阶段&#xff0c;开源之夏组织方也通过高校行系列活动进入各大高校&#xff0c;帮助高校开发者科普开源文化、开源活动、开源技术。 6月4日 开源之夏携手多位开源技术大咖、经验型选手走进西安电…

解决数据库重启问题

最近部署软件时&#xff0c;发现mysql会一直在重启&#xff0c;记录下解决办法&#xff1a; 1.删除/home/dataexa/install/docker/datas/mysql路径下的data文件夹 2.重新构建mysql docker-compose up -d --build mysql 3.停掉所有应用&#xff0c;在全部重启&#xff1a; do…

前后端交互过程中—各类文件/图片的上传、下载、显示转换

前后端交互过程中—各类文件/图片的上传、下载、显示转换 图片补充&#xff1a;new Blob()URL.createObjectURL()替代方案&#xff1a;FileReader.readAsDataURL()​​对比&#xff1a; tiff文件TIFF库TIFF转换通过url转换tiff文件为png通过文件选择的方式转换tiff文件为png 下…

数据库同步是什么意思?数据库架构有哪些?

目录 一、数据库同步是什么 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;数据库同步的类型 &#xff08;三&#xff09;数据库同步的实现方式 二、数据库架构的类型 &#xff08;一&#xff09;单机架构 &#xff08;二&#xff09;主从复制架构 &a…

【数据结构】详解算法复杂度:时间复杂度和空间复杂度

&#x1f525;个人主页&#xff1a;艾莉丝努力练剑 ❄专栏传送门&#xff1a;《C语言》、《数据结构与算法》 &#x1f349;学习方向&#xff1a;C/C方向 ⭐️人生格言&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平 前言&…