• 设计模式-单例模式


     单例模式 饿汉式 饱汉式

    单例模式是Java中最简单的设计模式之一,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

    单例模式虽然很简单,但它的花样一点都不少,我们一一来看。

    1、饿汉式

    饿汉式,顾名思义,就是我很饿,迫不及待。不管有没有人用,先创建了再说。

    比如在Dubbo中的这段代码,创建一个配置管理器。

    1. public class ConfigManager {
    2. private static final ConfigManager configManager = new ConfigManager();
    3. private ConfigManager() {}
    4. public static ConfigManager getInstance() {
    5. return configManager;
    6. }
    7. }

    又或者在RocketMQ中,创建一个MQ客户端实例的时候。

    1. public class MQClientManager {
    2. private static MQClientManager instance = new MQClientManager();
    3. private MQClientManager() {}
    4. public static MQClientManager getInstance() {
    5. return instance;
    6. }
    7. }

    2、懒汉式

    懒汉式是对应饿汉式而言的。它旨在第一次调用才初始化,避免内存浪费。但为了线程安全和性能,一般都会使用双重检查锁的方式来创建。

    来看Seata框架中,通过这种方式来创建一个配置类。

    1. public class ConfigurationFactory{
    2. private static volatile Configuration CONFIG_INSTANCE = null;
    3. public static Configuration getInstance() {
    4. if (CONFIG_INSTANCE == null) {
    5. synchronized (Configuration.class) {
    6. if (CONFIG_INSTANCE == null) {
    7. CONFIG_INSTANCE = buildConfiguration();
    8. }
    9. }
    10. }
    11. return CONFIG_INSTANCE;
    12. }
    13. }

    3、静态内部类

    可以看到,通过双重检查锁的方式来创建单例对象,还是比较复杂的。又是加锁,又是判断两次,还需要加volatile修饰的。

    使用静态内部类的方式,可以达到双重检查锁相同的功效,但实现上简单了。

    在Seata框架中,创建RM事件处理程序器的时候,就使用了静态内部类的方式来创建单例对象。

    1. public class DefaultRMHandler extends AbstractRMHandler{
    2. protected DefaultRMHandler() {
    3. initRMHandlers();
    4. }
    5. private static class SingletonHolder {
    6. private static AbstractRMHandler INSTANCE = new DefaultRMHandler();
    7. }
    8. public static AbstractRMHandler get() {
    9. return DefaultRMHandler.SingletonHolder.INSTANCE;
    10. }
    11. }

    还有可以通过枚举的方式来创建单例对象,但这种方式并没有被广泛采用,。

    有人说,饿汉式的单例模式不好,不能做到延迟加载,浪费内存。事实上很多开源框架中,用的最多的就是这种方式。

    如果明确希望实现懒加载效果时,可以考虑用静态内部类的方式;如果还有其他特殊的需求,比如创建对象的过程比较繁琐,可以用双重检查锁的方式。

  • 相关阅读:
    QT源码拾贝6-10(qwindowswindow)
    android app启动卡在启动页面,无法启动。鸿蒙系统armony H4.0
    直流电机双闭环调速Simulink仿真
    Docker没有vim如何安装,apt-get update报ERR404解决方案
    如何用Excel做最小二乘法②
    java计算机毕业设计演唱会门票订售及管理系统源码+系统+数据库+lw文档
    python的环境安装(版本3.10.6)
    Spark3.0 Sql 使用HiveTableScanExec 读取Hive orc表源码分析及参数调优
    【论文阅读】FreeMatch: Self-adaptive Thresholding for Semi-supervised Learning
    从此以后,将硬件接入大语言模型(LLM)将变得如此简单~
  • 原文地址:https://blog.csdn.net/s178435865/article/details/137915831