单例模式(Singleton Pattern)

单例模式(Singleton Pattern) 单例模式是一种设计模式,确保一个类只有一个实例,并提供全局访问点。本文介绍了单例模式的两种实现方式:饿汉模式和懒汉模式。饿汉模式在程序启动时就创建实例,线程安全但可能浪费资源;懒汉模式在首次调用时创建实例,C++11后线程安全且更节省资源。文章详细解析了两种模式的代码实现、核心特点及适用场景,并对比了它们的优缺点。单例模式适用于需要全局唯一对象的场景,如配置管理、线程池等。建议根据实际需求选择实现方式,确保代码效率和安全性。 阅读详情

目录

定义

特点

单例模式的要点

单例模式根据实例化对象时机的不同分为两种

单例模式还有一种比较常见的形式:双重锁的形式

单例模式的优点

单例模式的缺点

适用场景

单例模式注意事项

关于Java中单例模式的一些常见问题

定义

单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。

特点

1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例

单例模式的要点

1、私有的构造方法

2、指向自己实例的私有静态引用

3、以自己实例为返回值的静态的公有的方法

单例模式根据实例化对象时机的不同分为两种

  • 饿汉式单例
public class Singleton {
    private static Singleton singleton = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return singleton;
    }
}
  • 懒汉式单例
public class Singleton {
    private static Singleton singleton;
    private Singleton(){}

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

单例模式还有一种比较常见的形式:双重锁的形式

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

这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。

这种模式中双重判断加同步的方式,比第一个例子中的效率大大提升,因为如果单层if判断,在服务器允许的情况下,假设有一百个线程,耗费的时间为100*(同步判断时间+if判断时间),而如果双重if判断,100的线程可以同时if判断,理论消耗的时间只有一个if判断的时间。

所以如果面对高并发的情况,而且采用的是懒汉模式,最好的选择就是双重判断加同步的方式。

单例模式的优点

1、在内存中只有一个对象,节省内存空间。

2、避免频繁的创建销毁对象,可以提高性能。

3、避免对共享资源的多重占用。

4、可以全局访问。

单例模式的缺点

1、扩展困难,由于getInstance静态函数没有办法生成子类的实例。如果要拓展,只有重写那个类。

2、隐式使用引起类结构不清晰。

3、导致程序内存泄露的问题。

适用场景

由于单例模式的以上优点,所以是编程中用的比较多的一种设计模式。以下为使用单例模式的场景:

       1、需要频繁实例化然后销毁的对象。

       2、创建对象时耗时过多或者耗资源过多,但又经常用到的对象。

       3、资源共享的情况下,避免由于资源操作时导致的性能或损耗等

       4、控制资源的情况下,方便资源之间的互相通信。

单例模式注意事项

只能使用单例类提供的方法得到单例对象,不要使用反射,否则将会实例化一个新对象。

不要做断开单例类对象与类中静态引用的危险操作。

多线程使用单例使用共享资源时,注意线程安全问题。

关于Java中单例模式的一些常见问题

单例模式的对象长时间不用会被jvm垃圾收集器收集吗

除非人为地断开单例中静态引用到单例对象的联接,否则jvm垃圾收集器是不会回收单例对象的。

jvm卸载类的判定条件如下:

1、该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。

2、加载该类的ClassLoader已经被回收。

3、该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

只有三个条件都满足,jvm才会在垃圾收集的时候卸载类。显然,单例的类不满足条件一,因此单例类也不会被回收。

在一个jvm中会出现多个单例吗

在分布式系统、多个类加载器、以及序列化的的情况下,会产生多个单例,这一点是无庸置疑的。那么在同一个jvm中,会不会产生单例呢?使用单例提供的getInstance()方法只能得到同一个单例,除非是使用反射方式,将会得到新的单例。

代码如下:

Class c = Class.forName(Singleton.class.getName());
Construtor ct = c.getDeclaredConstructor();
ct.setAccessible(true);
Singleton singleton = (Singleton)ct.newInstance();

这样,每次运行都会产生新的单例对象。所以运用单例模式时,一定注意不要使用反射产生新的单例对象。

在getInstance()方法上同步有优势还是仅同步必要的块更优优势?

因为锁定仅仅在创建实例时才有意义,然后其他时候实例仅仅是只读访问的,因此只同步必要的块的性能更优,并且是更好的选择。

缺点:只有在第一次调用的时候,才会出现生成2个对象,才必须要求同步。而一旦singleton 不为null,系统依旧花费同步锁开销,有点得不偿失。

单例类可以被继承吗

根据单例实例构造的时机和方式不同,单例模式还可以分成几种。但对于这种通过私有化构造函数,静态方法提供实例的单例类而言,是不支持继承的。

这种模式的单例实现要求每个具体的单例类自身来维护单例实例和限制多个实例的生成。但可以采用另外一种实现单例的思路:登记式单例,来使得单例对继承开放。

ESP32Servo库驱动SG90舵机:从入门到精准控制 本文详细介绍了如何使用ESP32Servo库驱动SG90舵机,从硬件连接到软件环境搭建,再到编写示例程序实现精准控制。内容涵盖库安装、基础驱动代码解析、舵机校准方法以及平滑运动控制,帮助开发者快速掌握ESP32控制舵机的核心技能,并提供了电源管理、信号抗干扰等实用避坑指南。 阅读详情

相关推荐

树莓派 SPI操作

扩展板配备一款0.96inch,128864分辨率的oled显示屏,通过SPI控制,先上显示效果图。由于程序过长,在这里我就不把代码全部贴出来了,只是简单讲解一下spi的操作函数。管脚如下如所有,左边方框的管脚分别为MOSI MISO SCLK,左边CE0,CE1为两个片选管脚,分别对应上图中的spidev0.0,spidev0.1两个设备。下载spidev库,复制到树莓派,并行运行如下命令解压安装。spi设备,此处设备为/dev/spi-decv0.0。在/dev路径下面,我们可以发现两个spi设备。

weixin_46529898的博客 914

Singleton Pattern 单例模式

单例的对象只能有一个实例存在

喝醉酒的小白 5011

Ansys CFX Pre 中 RGP 表的高级配置与优化策略

本文深入探讨了Ansys CFX Pre中RGP表的高级配置与优化策略,旨在帮助用户将仿真从“能用”提升至“精准好用”。文章重点解析了如何根据具体仿真场景,科学设定温度压力范围、选择流体类型,并针对相变等复杂工况实施网格加密与分离建表等关键优化技术,以显著提升计算精度与稳定性。

weixin_29216957的博客 1180

【设计模式】——单例模式(Singleton Pattern)

单例模式(Singleton Pattern)是这些设计模式中的一种,它提供了一种创建对象的最佳方式,确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。这种模式在需要严格控制资源访问、管理全局状态或实现共享资源访问时非常有用。

J^T的博客 4738

形式化方法(Formal Methods)和人工智能(Artificial Intelligence)

一、形式化方法(Formal Methods) ​ 形式化方法最初应用在硬件上,验证硬件的正确性,后面逐渐应用到软件编程中,能够在软件中找到软件的错误,验证软件的安全可靠。形式化方法更加接近离散数学,所以其应用难度非常大,同时学习成本也较高。再加上形式化方法的大多数理论还停留在上个世纪,由于程序越来越复杂,导致形式化方法进行验证需要大量人工和时间,以至于现在绝大部分软件开发人员完全没有考虑过这个方法,甚至没有听说过这个名词。 ​ 形式化方法最新的应用成果是在工业上,比如一些极其重要且对安全性要求极高的领域(

qq_37030400的博客 4004

架构设计之架构治理

架构治理的本质是“用规则约束复杂性,用流程保障落地,用数据驱动优化”先定目标:明确量化的治理目标,避免盲目行动;立标准:建立覆盖分层、选型、接口、拆分的统一规范,奠定治理基础;强评审:通过架构评审把控设计环节,提前规避风险;全流程:将治理规则贯穿设计、开发、测试、部署、运维全生命周期;重保障:通过组织、流程、工具确保治理落地,而非“纸上谈兵”;持续迭代:随业务与技术演进优化治理规则,避免“一劳永逸”。

xiaolyuh的专栏 810

singleton pattern 单例模式

摘要 在我们日常的工作中经常需要在应用程序中保持一个唯一的实例,如:IO处理,数据库操作等,由于这些对象都要占用重要的系统资源,所以我们必须限制这些实例的创建或始终使用一个公用的实例,这就是我们今天要介绍的——单例模式(Singleton Pattern)。 概念 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。 单例模式,也叫单子模式,是一种常用的软件设计模式...

TIANTIAN_ZZ的博客 224

【电磁场计算】磁偶极子在外磁场中的受力

最近在总结电磁场计算公式的时候发现,关于磁偶极子受力的计算公式,在不同文献中的说明有点出入,在此特地写一篇博客澄清一下。

sky4403的博客 7466

设计模式 - Singleton pattern 单例模式

单例模式是一种创建型设计模式,它用来保证一个类只有一个实例, 并且提供一个访问该实例的全局节点。其在很多场景中都有应用,比如数据库连接池、日志记录器、Spring中对象的创建等。总的来说,单例模式在需要控制实例数量、确保全局唯一性的场景中被广泛应用。单例模式通过限制类的实例化对象为一个,可以确保全局唯一性的场景中被广泛应用,从而有助于控制资源访问、简化全局访问点、减少内存占用等,在很多情况下都可以提升程序的运行效率。

WLKQNYJY_SHT的博客 4112

STM32CubeMX实战:FreeRTOS内存管理5种方案全解析(附heap_4避坑指南)

本文深入解析了STM32CubeMX环境下FreeRTOS的5种内存管理方案(heap_1到heap_5),重点介绍了heap_4的优化策略与避坑指南。通过对比分析各方案的特点、性能指标及适用场景,帮助开发者根据项目需求选择最优内存管理策略,提升嵌入式系统开发效率与稳定性。

aa123的博客 620

基于YOLO-world训练模型的完整教程:从数据准备到微调训练

本文提供了YOLO-world模型训练的完整教程,涵盖从环境配置到微调训练的全流程。首先介绍了YOLO-world项目的安装与配置步骤,包括依赖安装和CUDA环境设置;接着详细说明了数据集的准备方法,包括COCO格式数据集的组织结构和自定义数据集的类别定义;然后阐述了配置文件的修改要点,包括超参数调整和数据集路径设置;最后讲解了训练命令的使用方法及常见问题的解决方案。本教程旨在帮助读者快速掌握YOLO-world模型的训练技能,适用于计算机视觉领域的研究人员和开发者。

FJN110的博客 1108

单例模式 singleton pattern

1定义: 固定某个类只能有一个实例,类不可在外部被new出来,而是调用类的方法来获得实例 2.场景: 需要确保某类在任何时刻都只能有一个实例,在任何时刻保持全局唯一变量的情况下使用 3.实现: 难点是如何在多线程的情况下保证单例模式线程安全性,注意效率、空间占用、线程安全性这3点。先要理解多线程为啥会出现多个实例,我的理解就是类内部在 if instance==null 这步到 ins...

用自己的话说出来才算理解,用自己的方法做到才算会用 225

本地搭建 GitLab 14.1.0版本CI/CD

GitLab 镜像版本 gitlab/gitlab-ce:14.1.0-ce.0 GitLab Runner 镜像版本 gitlab/gitlab-runner:v14.1.0 搭建此套环境是在一台32G的windows电脑上安装的。 使用dokcer安装。 此外还涉及的软件Docker Desktop,WSL 安装GitLab 首先启动 dockcer,打开WSL 打开后 首先定义GitLab的持久化目录 export GITLAB_HOME=/srv/gitlab 然后运行安装GitLab的命令

知无涯 4491

单例模式【Singleton Pattern】

这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此的广泛,如此的有人缘,单例就是单一、独苗的意思,那什么是独一份呢?你的思维是独一份,除此之外还有什么不能山寨的呢?我们举个比较难复制的对象:皇帝中国的历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认为皇帝是个单例模式,在这个场景中,有皇帝,有大臣,大臣是天天要上朝参见皇帝的,今天参拜的皇帝应该和昨天、前天的一样(过渡期的不

admin1973的专栏 512

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

单例模式——Singleton Pattern

单例模式的核心作用就是保证一个类只有一个实例,并提供一个访问该实例的全局访问点【即提供一个public方法获取该实例】。 应用场景: Windows中的任务管理器项目开发中,读取配置文件的类通常也是单例模式。网站的计数器通常使用单例模式,否则不容易实现同步数据库的连接池的设计一般采用单例模式。在Spring中,每个Bean默认就是单例的,Spring MVC中,控制器对象也是单例的。Ser

不会停下学习的脚步,重在思考。 480

设计模式-01单例模式Singleton Pattern

单例模式是一种创建型设计模式,确保类只有一个实例并提供全局访问点。常见实现方式包括:饿汉式(线程安全但提前创建)、懒汉式(延迟加载需同步)、双重检查锁定(高性能线程安全)、静态内部类(线程安全延迟加载)和枚举单例(最佳实践,防止反序列化攻击)。该模式广泛应用于框架如Spring的ApplicationContext和Netty的EventLoopGroup等场景,适用于需要全局唯一实例的情况。

d3y1`5 81_09 1465

Singleton Pattern单例模式总结

在我们平时工作 或者 面试的时候,单例模式算是出现最频繁的一种设计模式了,本文整理了单例模式的各种实现 1、饿汉模式【简而言之,就是不管你用不用,我先创建出来】 public class HungrySingleton { private static final HungrySingleton hungry = new HungrySingleton(); privat...

qq_37254296的博客 212

单例模式 (Singleton Pattern)

单例模式是最简单也是最常用的创建型设计模式之一。它确保一个类只有一个实例,并提供全局访问点来获取这个实例。就像一个国家只能有一个总统,一个公司只能有一个CEO一样,有些资源在系统中确实应该保持唯一性。客户端1Singleton实例客户端2客户端3全局唯一实例 🤔 为什么需要单例模式? 📊 典型应用场景 场景 原因 举例 🗃️ 数据库连接池 避免频繁创建连接,节省资源 MySQL连接管理器 📝 日志记录器 统一日志输出,避免文件冲突 Log4cpp、spdlog ⚙️ 配置管理

苦哈哈的 C++ 程序员,写这个技术博客不是为了装逼,也不是为了立人设,是为了收割流量 1135

单例模式 Singleton Pattern

通过静态嵌套类( static nested class )的静态final变量存储 enclosing class 实例,从而实现lazy instantiation, 因为静态嵌套类只会在调用它时初始化一次。4. 如果单例对象支持序列化 Serialization,在反序列化时需要加上方法 readResolve, 直接替换反序列化对象为同一个 instance 对象。线程安全,且不被反射和反序列化破坏。若想阻止这种反射引起的破坏,可在私有构造器上判断是否已经初始化。测试 assertSame。

DachuiLi的博客 366
上一篇: 【面试题】抽象类和接口的联系和区别
下一篇: 工厂模式(Factory Pattern)
红枫忆梦
博客等级 码龄8年 117粉丝 279原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值