设计模式-3.1单例模式

文章介绍了单例模式的实现方式,包括饿汉式(类加载时创建实例)、懒汉式(首次使用时创建)以及推荐的枚举方式。枚举方式确保线程安全且仅加载一次。文章还讨论了单例模式的潜在问题,如内存浪费、线程安全、反序列化和反射破坏,并提供了双重检查锁和静态内部类的优化实现。
摘要由CSDN通过智能技术生成

📝 所有单例的实现都包含以下相同的步骤:

  • 📌 将默认构造函数设为私有, 防止其他对象使用单例类的 new 运算符。
  • 📌 新建一个静态构建方法作为构造函数。
  • ⚠️ 注意: 该函数会 “偷偷” 调用私有构造函数来创建对象,并将其保存在一个静态成员变量中。
  • ⚠️ 注意: 此后所有对于该函数的调用都将返回这一缓存对象。

📝 单例设计模式分类两种(枚举也是懒汉式):

  • 🚀 饿汉式:

    • 📌 类加载就会导致该单实例对象被创建。
  • 🛌 懒汉式:

    • 📌 类加载不会导致该单实例对象被创建。
    • ⚠️ 注意: 首次使用该对象时才会创建(这就是懒加载)。
  • 🎖 枚举方式(推荐):

    • 📌 枚举类型是线程安全的,并且只会装载一次。
    • 📌 枚举的写法非常简单。
    • ⚠️ 注意: 可以利用枚举的特性来解决线程安全和单一实例的问题。
    • ⚠️ 注意: 还可以防止反射和反序列化对单例的破坏。

饿汉式懒汉式是两种常见的单例模式创建方式,这些方式用于确保一个类只有一个实例,并提供一种全局访问点以访问该实例。

  • 饿汉式(Eager Initialization)
    • 📌 在饿汉式中,实例在类加载时就被创建。
    • 📌 优点是在多线程环境下是线程安全的。
    • ⚠️ 注意: 可能会浪费一些内存。
public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();
    
    private EagerSingleton() {
        // Private constructor to prevent instantiation.
    }
    
    public static EagerSingleton getInstance() {
        return instance;
    }
}
  • 懒汉式(Lazy Initialization)
    • 📌 在懒汉式中,实例只有在第一次被访问时才会被创建。
    • 📌 优点是节省了内存。
    • ⚠️ 注意: 需要考虑线程安全性。
public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {
        // Private constructor to prevent instantiation.
    }
    
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

⚠️ 注意: 上述的简单懒汉式实现虽然线程安全,但在高并发情况下,每次调用 getInstance 都需要加锁,可能影响性能。

⚠️ 注意: 单例模式在某些情况下可能不是最佳的设计选择,因为它会引入全局状态,可能会导致耦合和测试困难。


📝 存在的问题(枚举方式不存在的)


  • 🚫 内存浪费:

    • 📌 适用于: 饿汉式
    • ⚠️ 注意: 由于实例在类加载时就被创建,即使后续可能并未使用,也会占用内存。
  • 🚫 线程安全:

    • 📌 适用于: 懒汉式
    • ⚠️ 注意: 在多线程环境下,没有采取额外的措施可能会导致创建多个实例。
  • 🚫 反序列化破坏:

    • 📌 适用于: 大多数单例实现方式。
    • ⚠️ 注意: 反序列化会调用反射,多次反序列化产生的对象是不一致的。
    • ⚠️ 注意: 序列化多次保存相同的对象时,实际保存的只是第一个对象的引用。
  • 🚫 反射破坏:

    • 📌 适用于: 大多数单例实现方式。
    • ⚠️ 注意: 通过反射的方式可以调用私有的构造方法,从而破坏单例原则。

📝 几种优秀的单例模式代码示例


📌 双重检查锁方式(可以被序列化和反射破化)

package com.study.notes.design.patterns.pattern.create.singleton.demo4;

/**
 * @version v1.0
 * @ClassName: Singleton
 * @Description: 双重检查锁方式
 * 双重检查锁模式是一种非常好的单例实现模式,解决了单例、性能、线程安全问题,上面的双重检测锁模式看上去完美无缺,
 * 其实是存在问题,在多线程的情况下,可能会出现空指针问题,出现问题的原因是JVM在实例化对象的时候会进行优化和指今重排序操作。
 * 要解决双重检查锁模式带来空指针异常的问题,只需要使用 volatile 关键字,volatile 关键字可以保证可见性和有序性。
 * volatile是Java虚拟机提供的轻量级同步机制。
 * 保证可见性
 * 不保证原子性
 * 禁止指令重排(保证有序性)
 * @Author: lzq
 */
public class Singleton {

    //声明Singleton类型的变量
    private static volatile Singleton instance;

    //私有构造方法
    private Singleton() {
    }

    //对外提供公共的访问方式
    public static Singleton getInstance() {
        //第一次判断,如果instance的值不为null,不需要抢占锁,直接返回对象
        if (instance == null) {
            synchronized (Singleton.class) {
                //第二次判断
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}


📌 静态内部类(加入了防止序列化和反射破化的代码)

package com.study.notes.design.patterns.pattern.create.singleton.demo7;

import java.io.Serializable;

/**
 * @version v1.0
 * @ClassName: Singleton
 * @Description: 静态内部类方式
 * 序列化、反序列方式破坏单例模式的解决方法
 * 在Singleton类中添加readResolve方法,在反序列化时被反射调用,如果定义了这个方法,就返回这个方法的值,如果没有定义,则返回新new出来的对象。
 * @Author: lzq
 */
public class Singleton implements Serializable {

    private static boolean flag = false;

    //私有构造方法
    private Singleton() {
        synchronized (Singleton.class) {
            //判断flag的值是否是true,如果是true,说明非第一次访问,直接抛一个异常,如果是false的话,说明第一次访问
            if (flag) {
                throw new RuntimeException("不能创建多个对象");
            }
            //将flag的值设置为true
            flag = true;
        }
    }

    //提供公共的访问方式
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }

    //当进行反序列化时,会自动调用该方法,将该方法的返回值直接返回
    public Object readResolve() {
        return SingletonHolder.INSTANCE;
    }

    //定义一个静态内部类
    private static class SingletonHolder {
        //在内部类中声明并初始化外部类的对象
        private static final Singleton INSTANCE = new Singleton();
    }

}


📌 枚举形式(最好的)

package com.study.notes.design.patterns.pattern.create.singleton.demo6;

/**
 * @version v1.0
 * @ClassName: Singleton
 * @Description: 枚举实现方式
 * 枚举类型是线程安全的,并且只会装载一次,枚举的写法非常简单,可以利用枚举的特性来解决线程安全和单一实例的问题,
 * 还可以可以防止反射和反序列化对单例的破坏,而且枚举类型是所用单例实现中唯一一种不会被破坏的单例实现模式。
 * <p>
 * 在代码中,我们首先将Singleton类的构造函数设置为private私有的,然后在Singleton类中定义一个静态的枚举类型SingletonEnum。
 * 在SingletonEnum中定义了枚举类型的实例对象Singleton,再按照单例模式的要求在其中定义一个Singleton类型的对象instance,其初始值为null;
 * 我们需要将SingletonEnum的构造函数改为私有的,在私有构造函数中创建一个Singleton的实例对象;最后在getInstance()方法中返回该对象。
 * 在实现过程中,Java虚拟机会保证枚举类型不能被反射并且构造函数只被执行一次。
 * * @Author: lzq
 */
public class Singleton {
    private Singleton() {
    }

    public static enum SingletonEnum {
        SINGLETON;
        private Singleton instance = null;

        private SingletonEnum() {
            instance = new Singleton();
        }

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: "OIF-CEI-3.1" 是 OIF (Optical Internetworking Forum) 的一项协议规范,用于描述与光网络有关的特定功能和要求。OIF 是一个国际性组织,致力于推动光网络的发展和标准化。而 CEI (Common Electrical Interface) 是指在光纤通信系统中使用的一种电子接口标准。 OIF-CEI-3.1 是 OIF 为了提高光纤通信系统的传输效率而制定的一项技术规范。它旨在提供一种高速、可靠的电子接口标准,促进光纤通信系统的互操作性和可扩展性。 OIF-CEI-3.1 的主要特点和功能包括以下几个方面: 1. 高速传输:OIF-CEI-3.1 支持高达100 Gbps的数据传输速率,能够满足现代光纤通信系统对大带宽的需求。 2. 低功耗:OIF-CEI-3.1 的设计考虑了功耗优化,提供了节能的通信解决方案,有助于减少电力消耗和碳排放。 3. 信号完整性:OIF-CEI-3.1 提供了一套严格的电信号传输要求,包括时钟回复、抖动控制等,确保数据传输的可靠性和稳定性。 4. 灵活性和可扩展性:OIF-CEI-3.1 支持多种传输模式和物理层配置,能够适应不同的光纤通信场景和需求。 5. 互操作性:OIF-CEI-3.1 是一个开放的标准化协议,减少了不同供应商之间的兼容性问题,提高了设备之间的互操作性。 总的来说,OIF-CEI-3.1 是一个重要的光纤通信标准,旨在推动高速、低功耗、可靠的光纤通信系统的发展。它提供了一套规范和要求,使得不同设备和技术能够互相配合和兼容,为光网络的部署和应用提供了良好的支持。 ### 回答2: OIF-CEI-3.1是一种光学互连框架的标准,旨在通过提供高速、高效、互操作的光纤通信解决方案来促进光学层面的互连技术的发展。它定义了光学模块之间的接口标准,以确保不同供应商的光学设备能够无缝地协同工作。 OIF-CEI-3.1标准主要关注的是高速数据传输,它通过制定规范来确保光学设备之间的兼容性和稳定性。这有助于降低系统集成的复杂性,提高系统的性能和可靠性。 OIF-CEI-3.1标准支持多种传输速率,包括10、25、50和100 Gbps。它定义了物理层接口的电气规范、引脚功能和信号传输特性。这使得不同厂家的设备可以在相同的速率下相互连接,加强了市场竞争力,降低了用户的成本。 该标准还考虑了功耗的问题,通过优化设计和算法,减少了设备的能耗。此外,OIF-CEI-3.1也关注了时钟和时序的同步问题,确保数据的可靠性和稳定性。 总之,OIF-CEI-3.1标准是光纤通信领域的重要标杆,它推动了光学互连技术的发展,提高了系统的性能和可靠性。用户可以在不同供应商间选择适合自己需求的设备,并且能够在不同速率下进行互连,提高了系统的灵活性并降低了成本。 ### 回答3: OIF-CEI-3.1是光互操作性论坛(OIF)制定的一种光纤连接接口规范。OIF是一个国际组织,旨在推动和发展光纤通信技术的互操作性。OIF-CEI-3.1规范主要用于高速串行数据传输,如数据中心、互联网交换机等领域。 OIF-CEI-3.1规范通过定义高速信号传输时的电气特性和接口标准,确保不同厂商生产的设备之间能够正常互联。该规范对信号的传输速率、电压、时钟恢复等关键参数进行了详细说明,以确保数据传输的可靠性和稳定性。 OIF-CEI-3.1规范在技术上有一些改进和更新,以适应不断增长的数据传输需求。其中包括更高的传输速率、更低的功耗和更好的时钟恢复性能等。这些特性对于数据中心等应用领域来说十分重要,因为它们需要高速、可靠的数据传输,并且要尽可能降低功耗。 OIF-CEI-3.1规范的实施对于光纤连接技术的发展和应用有着积极的意义。它提高了设备之间的互操作性,降低了不同厂商设备之间的兼容性问题,促进了市场竞争和创新。此外,它还为数据中心等应用场景提供了更快速、更可靠的数据传输解决方案。 总之,OIF-CEI-3.1规范是一个具有重要意义的光纤连接接口标准,它通过定义电气特性和接口标准,确保高速数据传输的可靠性,推动了光纤通信技术的发展和应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yueerba126

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值