️【设计模式】之单例模式详解:创建者模式中的一颗“明珠”

全文目录:

    • 开篇语
    • [🎯 什么是单例模式?](#🎯 什么是单例模式?)
    • [🗂️ 单例模式的关键特性](#🗂️ 单例模式的关键特性)
    • [🔑 单例模式的实现方式](#🔑 单例模式的实现方式)
      • [1. 🌱 懒汉式单例(Lazy Initialization)](#1. 🌱 懒汉式单例(Lazy Initialization))
      • [2. 🔒 懒汉式单例(线程安全版)](#2. 🔒 懒汉式单例(线程安全版))
      • [3. ⚙️ 双重检查锁(Double-Checked Locking)](#3. ⚙️ 双重检查锁(Double-Checked Locking))
      • [4. 🌐 饿汉式单例(Eager Initialization)](#4. 🌐 饿汉式单例(Eager Initialization))
      • [5. 💥 静态内部类(Initialization on Demand Holder Idiom)](#5. 💥 静态内部类(Initialization on Demand Holder Idiom))
    • [📌 单例模式的应用场景](#📌 单例模式的应用场景)
    • [🤔 单例模式的优缺点](#🤔 单例模式的优缺点)
    • [🎓 进阶技巧:如何优化单例模式的实现?](#🎓 进阶技巧:如何优化单例模式的实现?)
    • [🧩 小结:单例模式的核心与实战技巧](#🧩 小结:单例模式的核心与实战技巧)
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言

在软件设计中,单例模式被誉为设计模式中的"最小化实例管理专家"。它的核心思想在于确保一个类在整个系统中只有一个实例,并且能提供一个全局访问点。今天,让我们深入探讨单例模式,了解它在创建者模式中的独特魅力、使用场景和常见实现方式。💡


🎯 什么是单例模式?

单例模式(Singleton Pattern)是一种创建型设计模式,其主要目的是保证某个类在系统中只有一个实例 ,并且提供一个访问该实例的全局访问点 。通常用于那些需要共享全局状态的对象,如配置管理器、日志记录器、数据库连接池等。


🗂️ 单例模式的关键特性

  1. 唯一性:单例模式确保某个类在整个系统中只有一个实例。
  2. 全局访问:通过静态方法,可以在任何地方访问这个唯一的实例。
  3. 延迟初始化:单例模式通常采用"懒汉式"实现,在需要时再初始化,节省系统资源。

🔑 单例模式的实现方式

单例模式的实现方式有多种,常见的有以下几种:

1. 🌱 懒汉式单例(Lazy Initialization)

懒汉式是最简单的实现方式,在第一次调用时才创建实例。

java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

特点

  • 优点:延迟加载,资源利用率高。
  • 缺点:在多线程环境下不安全,可能会创建多个实例。

2. 🔒 懒汉式单例(线程安全版)

通过同步方法实现线程安全的单例,但会降低效率。

java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

特点

  • 优点:线程安全,确保唯一实例。
  • 缺点:同步操作增加了开销,效率较低。

3. ⚙️ 双重检查锁(Double-Checked Locking)

双重检查锁避免了每次访问都加锁,提高了效率。

java 复制代码
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;
    }
}

特点

  • 优点:高效,线程安全。
  • 缺点:代码稍复杂,但是目前最优的懒汉式单例实现方式。

4. 🌐 饿汉式单例(Eager Initialization)

饿汉式单例在类加载时就创建实例,因此不需要考虑线程安全问题。

java 复制代码
public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

特点

  • 优点:简单,线程安全。
  • 缺点:不支持延迟加载,类加载时即创建实例,可能浪费资源。

5. 💥 静态内部类(Initialization on Demand Holder Idiom)

静态内部类实现方式是单例模式中一个较为推荐的实现方式,利用了类加载机制来确保线程安全。

java 复制代码
public class Singleton {
    private Singleton() {}

    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

特点

  • 优点:线程安全,延迟加载,效率高。
  • 缺点:代码结构复杂,理解门槛略高。

📌 单例模式的应用场景

单例模式在以下场景中非常常用:

  1. 配置管理:在系统中需要一个唯一的配置管理器实例,确保不同模块使用相同的配置信息。
  2. 日志管理:在整个应用程序中仅需一个日志记录对象,用于写入日志文件。
  3. 数据库连接池:多个数据库操作共用同一个数据库连接池实例,节省资源。
  4. 缓存:系统缓存的单一实例,便于管理和统一访问。
  5. 系统资源管理:某些系统资源(如文件系统或打印机)需要全局访问。

🤔 单例模式的优缺点

优点

  • 减少内存开销:因为系统中只会有一个实例,不会占用过多的内存。
  • 全局访问:提供一个全局访问点,使得不同模块能够方便地访问同一个实例。
  • 线程安全:结合适当的实现方式,可以在多线程环境下安全地访问单例对象。

缺点

  • 不易扩展:由于类的构造方法是私有的,继承和扩展会比较困难。
  • 测试难度增加:单例模式由于是全局共享的,容易产生"共享状态",对单元测试不太友好。

🎓 进阶技巧:如何优化单例模式的实现?

  1. 使用反射与序列化保护

    单例模式的一个潜在风险在于可以通过反射和序列化来创建多个实例。可以在构造方法中加入判断逻辑,阻止二次实例化。

    java 复制代码
    private Singleton() {
        if (instance != null) {
            throw new IllegalStateException("Already initialized");
        }
    }
  2. 防止序列化破坏单例

    单例类实现Serializable接口后,可以通过实现readResolve方法来确保序列化后的实例唯一性。

    java 复制代码
    protected Object readResolve() {
        return getInstance();
    }
  3. 枚举单例

    Java提供了基于枚举的单例实现,这是最简单且有效的单例实现方式,能够自动支持线程安全并防止反射攻击。

    java 复制代码
    public enum Singleton {
        INSTANCE;
        
        public void doSomething() {
            // 方法实现
        }
    }

    特点

    • 简单易用,线程安全且防止序列化和反射破坏。

🧩 小结:单例模式的核心与实战技巧

单例模式在创建者模式中堪称经典,通过限制实例数量和全局访问的方式,解决了系统中资源共享的问题。无论是在配置管理、日志记录还是数据库连接池的管理上,单例模式都是开发者的好帮手。

总结小技巧:

  • 在多线程环境下,尽量选择线程安全的实现方式,比如双重检查锁和静态内部类。
  • 如果需要防止反射和序列化破坏单例,可以选择枚举单例实现。
  • 在设计单例时,考虑其使用场景,避免不必要的资源浪费和过度封装。

希望这篇文章帮助你深入理解单例设计模式的实现和应用,为你的开发旅程增添一份智慧!

... ...

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

... ...

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

相关推荐
GIS好难学1 小时前
《Vue进阶教程》第六课:computed()函数详解(上)
前端·javascript·vue.js
执键行天涯1 小时前
element-plus中的resetFields()方法
前端·javascript·vue.js
Days20501 小时前
uniapp小程序增加加载功能
开发语言·前端·javascript
喵喵酱仔__1 小时前
vue 给div增加title属性
前端·javascript·vue.js
界面开发小八哥2 小时前
LightningChart JS助力德国医疗设备商打造高精度肺功能诊断软件
javascript·信息可视化·数据可视化·lightningchart·图表工具
不会玩技术的技术girl2 小时前
使用HTML获取商品详情:技术实现与最佳实践
前端·javascript·html
西岭千秋雪_2 小时前
设计模式の单例&工厂&原型模式
java·单例模式·设计模式·简单工厂模式·工厂方法模式·抽象工厂模式·原型模式
carcarrot2 小时前
一些前端组件介绍
前端·javascript
疯狂的沙粒3 小时前
JavaScript 单例模式的创建与应用
开发语言·前端·javascript·vue.js
陈大爷(有低保)3 小时前
LayUI结合SSM框架
前端·javascript·layui