首页 > 编程语言 >重生之我在Java世界------学单例设计模式

重生之我在Java世界------学单例设计模式

时间:2024-09-16 19:54:41浏览次数:9  
标签:Singleton Java instance 实例 单例 ------ 设计模式 public 加载

什么是单例设计模式?

单例模式是面向对象编程中最简单却又最常用的设计模式之一。它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的原理、常见实现方法、优缺点,以及在使用过程中可能遇到的陷阱。

单例模式的核心原理

单例模式的实现主要依赖于以下三个要素:

  1. 私有构造函数:防止外部直接创建实例。
  2. 私有静态实例:类的唯一实例。
  3. 公共静态访问方法:提供全局访问点。

这种设计确保了在整个应用程序中,特定的类只会有一个实例存在。单例模式常用于管理共享资源、全局配置或需要统一协调行为的场景。

常见实现方法

懒汉式(线程不安全)

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

这种方法实现了延迟加载,即在第一次调用 getInstance() 方法时才创建实例。然而,它在多线程环境下是不安全的。如果多个线程同时调用 getInstance() 方法,可能会创建多个实例。

饿汉式

public class Singleton {
    private static final Singleton instance = new Singleton();
    private Singleton() {}
    
    public static Singleton getInstance() {
        return instance;
    }
}

饿汉式在类加载时就创建了实例,因此天然线程安全。但它没有实现延迟加载,可能会造成资源浪费。

双重检查锁

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

双重检查锁结合了延迟加载和线程安全的优点。它在多线程环境下能够良好工作,同时避免了不必要的同步开销。

静态内部类

public class Singleton {
    private Singleton() {}
    
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

静态内部类方法既实现了**延迟加载,又保证了线程安全。**它利用了Java的类加载机制来保证只创建一个实例。当 Singleton 类被加载时,SingletonHolder 类并不会被立即初始化,只有当调用 getInstance() 方法时,SingletonHolder 才会被加载,从而创建 INSTANCE。这种方法也被称为 Initialization on Demand Holder (IODH) 模式。

枚举

public enum Singleton {
    INSTANCE;
    
    public void doSomething() {
        // 方法实现
    }
}

枚举实现是最简洁的单例模式实现方式。它不仅能避免多线程同步问题,还能防止反序列化重新创建新的对象。。

单例模式的优缺点

**单例模式的主要优点在于它能够确保一个类只有一个实例,提供了对该实例的全局访问点,**并且可以显著节省系统资源。然而,它也存在一些缺点。单例类可能会违反单一职责原则,因为它不仅要管理自己的功能,还要确保自己是唯一实例。此外,单例模式在某些情况下可能会使单元测试变得困难,因为很难模拟单例类的不同状态。

单例模式的潜在陷阱(拓展)

反射机制破坏单例

Java的反射机制可以用来破坏单例。通过反射,可以强制调用私有构造函数,从而创建多个实例。例如:

Singleton instance1 = Singleton.getInstance();
Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
Singleton instance2 = constructor.newInstance();

为了防止这种情况,可以在构造函数中添加检查,如果实例已经存在,则抛出异常。枚举实现的单例可以有效防止反射攻击。

序列化破坏单例

如果单例类是可序列化的,那么在反序列化时会创建新的实例。为了防止这种情况,可以实现 readResolve() 方法:

private Object readResolve() {
    return getInstance();
}

同样,枚举实现的单例也天然地防止了序列化问题。

多个类加载器

在使用多个类加载器的环境中,可能会出现多个单例实例。这种情况比较少见,但在复杂的应用服务器环境中可能会遇到。解决方法包括使用上下文类加载器或将单例类放在共享的类路径中。

结语

单例模式虽然概念简单,但在实际应用中需要考虑诸多因素,如线程安全、延迟加载、序列化等。选择合适的实现方法并注意潜在的陷阱,对于正确使用单例模式至关重要。在使用单例模式时,应该根据具体的应用场景和需求,权衡其利弊,做出最适合的选择。

从上述几种实现方法来看,静态内部类和枚举实现都提供了很好的平衡:它们既保证了线程安全,又兼顾了延迟加载(静态内部类)或简洁性(枚举)。特别是枚举实现,它还额外提供了防止反射攻击和序列化问题的保护。

标签:Singleton,Java,instance,实例,单例,------,设计模式,public,加载
From: https://blog.csdn.net/weixin_52007179/article/details/142306193

相关文章

  • 鸿蒙应用开发快速学习指南(初级篇-7 从网络获取数据)
    从网络获取数据第七课:从网络获取数据本节课的内容主要是如何使用http请求模块,依旧是从习题开始。判断题在http模块中,多个请求可以使用同一个httpRequest对象,httpRequest对象可以复用:正确(True)错误(False)从没有听过这种说法,选错误。拿下。使用on(type:‘headersRec......
  • 基于springboot的图书商城管理系统。Javaee项目,springboot项目。
    演示视频:基于springboot的图书商城管理系统。Javaee项目,springboot项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringBoot+Mybatis+Maven+Layui+Thymeleaf来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统。界面简洁......
  • Springboot宠物领养管理系统。Javaee项目。Springboot项目。
    演示视频:Springboot宠物领养管理系统。Javaee项目。Springboot项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringBoot+Mybatis+Vue+Maven来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统。界面简洁,操作简单。系统......
  • 基于springboot的家庭理财管理系统。Javaee项目,springboot项目。
    演示视频:基于springboot的家庭理财管理系统。Javaee项目,springboot项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringBoot+Maven+Layui来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统。分为系统管理员,家主,用户三类身......
  • Springboot+vue汽车销售管理系统。Javaee项目,springboot vue前后端分离项目。
    演示视频:Springboot+vue汽车销售管理系统。Javaee项目,springbootvue前后端分离项目。系统介绍:本文设计了一个基于Springboot+vue的前后端分离的汽车销售管理系统,采用M(model)V(view)C(controller)三层体系结构,通过SpringBoot+Vue+maven+IDEA来实现。有经理和销售两种角......
  • Yolov5水果分类识别+pyqt交互式界面
    Yolov5FruitsDetectorYolov5是一种先进的目标检测算法,可以应用于水果分类识别任务。结合PyQT框架,可以创建一个交互式界面,使用户能够方便地上传图片并获取水果分类结果。以下将详细阐述Yolov5水果分类识别和PyQT交互式界面的实现。Yolov5是由Ultralytics公司开......
  • GB28181在融合指挥调度系统应用方案探究和技术实现
    GB28181规范在融合指挥调度系统主要围绕实现视频监控系统的互联互通、音视频数据的实时传输与控制、以及应急指挥调度的高效性展开。一、GB28181规范概述GB/T28181是中国国家标准《安全防范视频监控联网系统信息传输、交换、控制技术要求》的编号,该标准规定了安全防范视频监控联网......
  • yolov5障碍物识别-雪糕筒识别(代码+教程)
    简介这是一个检测交通锥并识别颜色的项目。我使用yolov5来训练和检测视锥细胞。此外,我使用k均值来确定主色,以对锥体颜色进行分类。目前,支持的颜色为红色、黄色、绿色和蓝色。其他颜色被归类为未知。数据集和注释我使用了一个自收集的锥体数据集,其中包含303张锥体......
  • SmartMediaKit生态圈模块特点和应用场景
    SmartMediaKit概述大牛直播SDK跨平台的流媒体内核组件SmartMediaKit,支持Windows、Linux、Android、iOS等多个平台。其架构设计以模块化为核心,提供了高度可扩展性和自适应算法,以满足不同行业和应用场景的需求。1.核心功能模块直播推送模块:支持RTMP、RTSP等多种推流协议,以及H.264、H......
  • ASCII字符和中文字符的显示
    目录前言ASCII字符的点阵显示获取点阵描点main中文字符的点阵显示指定编码格式汉字区位码汉字点阵显示实验打开汉字库文件编写显示汉字的函数使用lcd_put_chinese函数前言        板子为韦东山老师的imx6ull板,要在LCD上实现字符的显示,要先实现我之前......