设计模式,单例模式

老生常谈了,

最佳实践无非是 懒汉 线程 安全的  , 双重判断 的 单例模式

双重检查锁(Double-Checked Locking)

双重检查锁定是一种优化版的懒汉式单例模式,它通过减少加锁的次数来提高性能。在首次检查时,如果实例已经创建,则不进行加锁;否则,在第二次检查时才加锁。

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 关键字保证了实例的创建过程在多线程环境下的可见性,并且避免了在多线程环境下因指令重排而导致的问题。

juc 讲过这些 可见性关键字和加锁啥的,ojbk的,

黑马视频的文案和菜鸟教程一样的,不知道都从哪里抄的

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

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

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

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

概要

单例模式(Singleton Pattern)

意图

确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

主要解决

频繁创建和销毁全局使用的类实例的问题。

何时使用

当需要控制实例数目,节省系统资源时。

如何解决

检查系统是否已经存在该单例,如果存在则返回该实例;如果不存在则创建一个新实例。

关键代码

构造函数是私有的。

应用实例

  • 一个班级只有一个班主任。
  • Windows 在多进程多线程环境下操作文件时,避免多个进程或线程同时操作一个文件,需要通过唯一实例进行处理。
  • 设备管理器设计为单例模式,例如电脑有两台打印机,避免同时打印同一个文件。

优点

  • 内存中只有一个实例,减少内存开销,尤其是频繁创建和销毁实例时(如管理学院首页页面缓存)。
  • 避免资源的多重占用(如写文件操作)。

缺点

  • 没有接口,不能继承。
  • 与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心实例化方式。

使用场景

  • 生成唯一序列号。
  • WEB 中的计数器,避免每次刷新都在数据库中增加计数,先缓存起来。
  • 创建消耗资源过多的对象,如 I/O 与数据库连接等。

注意事项

  • 线程安全getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成实例被多次创建。
  • 延迟初始化:实例在第一次调用 getInstance() 方法时创建。
  • 序列化和反序列化:重写 readResolve 方法以确保反序列化时不会创建新的实例。
  • 反射攻击:在构造函数中添加防护代码,防止通过反射创建新实例。
  • 类加载器问题:注意复杂类加载环境可能导致的多个实例问题。

结构

单例模式包含以下几个主要角色:

  • 单例类:包含单例实例的类,通常将构造函数声明为私有。
  • 静态成员变量:用于存储单例实例的静态成员变量。
  • 获取实例方法:静态方法,用于获取单例实例。
  • 私有构造函数:防止外部直接实例化单例类。
  • 线程安全处理:确保在多线程环境下单例实例的创建是安全的。

实现

我们将创建一个 SingleObject 类。SingleObject 类有它的私有构造函数和本身的一个静态实例。

SingleObject 类提供了一个静态方法,供外界获取它的静态实例。SingletonPatternDemo 类使用 SingleObject 类来获取 SingleObject 对象。

跳着看就行了,废话太多,菜鸟教程都有

单例模式这个,过一遍就行,之前学过了,

很基础的东西,没啥好说的,

破坏单例模式

总结

破坏单例模式的方法多种多样,常见的包括:

  • 通过反射访问私有构造器。
  • 通过序列化与反序列化。
  • 通过克隆。
  • 在多线程环境中没有同步控制。
  • 通过不同的类加载器。

为了防止单例模式被破坏,通常我们可以:

  • 使用 readResolve 方法来避免反序列化破坏单例。
  • 重写 clone() 方法或实现 Cloneable 接口时抛出异常。
  • 使用同步机制来保证懒汉式单例的线程安全。

如果你的单例类需要更强的安全性,考虑使用 enum 类型的单例模式,它天生是线程安全的并且不会被反射、序列化或克隆破坏。

单例模式这个, 快速过一遍就行,不需要全部看,

用到再看,快速过,

后边还有很多要看的,

sb视频。

单例模式,sb视频, 事无巨细,讲了全部种类单例模式的实现,还有单例模式的破坏,例子很垃圾,

对于单例模式,不需要去记忆和知道这么多实现细节,

只需要掌握 大概,单例模式有很多种,懒汉,恶汉,静态,枚举,双重确认啥的,线程安全,

还有破坏单例的过一眼即可

知道单例的目的是 节省资源就行。

对于大多数开发者来说,学习和应用单例模式并不需要记住过多的实现细节。掌握单例模式的核心概念和常见的几种实现方式就足够了。简而言之,单例模式的关键点在于:

  1. 目的是节省资源:确保某个类只有一个实例,避免多次创建,节省内存和系统资源。

  2. 常见的几种实现方式

    • 懒汉式(Lazy Initialization):实例在第一次使用时创建。
    • 饿汉式(Eager Initialization):类加载时就创建实例,适合没有复杂初始化逻辑的场景。
    • 静态内部类(Bill Pugh):结合懒加载和线程安全,推荐使用的方式。
    • 双重检查锁(Double-Checked Locking):使用同步保证线程安全,避免性能损失。
    • 枚举类型:推荐的实现方式,线程安全且防止反射攻击。
  3. 单例模式的破坏方式

    • 反射:反射可以访问私有构造函数,创建多个实例。
    • 序列化和反序列化:反序列化时,可能会创建新的实例。
    • 克隆:如果类实现了 Cloneable 接口,可以通过 clone() 方法创建副本。
    • 多线程问题:如果没有适当同步,懒汉式实现可能导致多次创建实例。

重点总结:

  • 单例模式的目标:确保一个类有且只有一个实例,避免资源浪费。
  • 常见实现方式:懒汉式、饿汉式、静态内部类、双重检查锁、枚举。
  • 线程安全:确保在多线程环境下也能正确工作。
  • 破坏方式:反射、序列化、克隆、线程问题。

不需要对每个细节过分纠结,理解这些常见的实现方式和破坏方式即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值