news 2026/4/16 14:07:19

Java设计模式:你见过大厂是怎么玩单列模式的吗?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java设计模式:你见过大厂是怎么玩单列模式的吗?

单例模式,是设计模式中最常见的模式之一,它是一种创建对象模式,用于产生一个对象的具体实例,可以确保系统中一个类只会产生一个实例。

单例模式

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

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

对于单列模式,在单例类的内部创建它的唯一实例,并通过静态方法getInstance()让客户端可以使用它的唯一实例;为了防止在外部对单例类实例化,将其构造函数的可见性设置为private,在单例类内部定义一个singleton类型的静态对象作为供外部共享访问的唯一实例

单例模式的特点:

1.单例类只能有一个实例

2.这个实例必须由单例类自己创建

3.单例类需要提供给外界访问这个实例

单例模式的作用:

单例模式主要为了保证在Java应用程序中,一个类只有一个实例存在。

所有需要调用的地方都共享这一单例对象。实现方式:构造方法的重载,将构造方法设置为私有。

单例模式的结构

单例模式主要有以下角色:

单例类

只能创建一个实例的类

访问类

测试类,就是使用单例类的类

优缺点

优点

对于频繁使用的对象,可以省去 new 操作花费的时间,尤其对那些重量级对象而言,削减了一笔非常客观的系统开销。

由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,从而减轻 GC 压力,缩短 GC 停顿时间。

缺点

单例模式一般没有接口,扩展困难。如果要扩展,则除了修改原来的代码,没有第二种途径,违背开闭原则。

在并发测试中,单例模式不利于代码调试。在调试过程中,如果单例中的代码没有执行完,也不能模拟生成一个新的对象。

单例模式的功能代码通常写在一个类中,如果功能设计不合理,则很容易违背单一职责原则。

常见写法

双重检查模式

public class Singleton {

private volatile static Singleton singleton; //1:volatile修饰

private Singleton (){}

public static Singleton getSingleton() {

if (singleton == null) { //2:减少不要同步,优化性能

synchronized (Singleton.class) { // 3:同步,线程安全

if (singleton == null) {

singleton = new Singleton(); //4:创建singleton 对象

}

}

}

return singleton;

}

}

推荐理由:

延迟初始化。和懒汉模式一致,只有在初次调用静态方法getSingleton,才会初始化signleton实例。

性能优化。同步会造成性能下降,在同步前通过判读singleton是否初始化,减少不必要的同步开销。

线程安全。同步创建Singleton对象,同时注意到静态变量singleton使用volatile修饰。

为什么要使用volatile修饰?

虽然已经使用synchronized进行同步,但在第4步创建对象时,会有下面的伪代码:

memory=allocate(); //1:分配内存空间

ctorInstance(); //2:初始化对象

singleton=memory; //3:设置singleton指向刚排序的内存空间

当线程A在执行上面伪代码时,2和3可能会发生重排序,因为重排序并不影响运行结果,还可以提升性能,所以JVM是允许的。如果此时伪代码发生重排序,步骤变为1->3->2,线程A执行到第3步时,线程B调用getsingleton方法,在判断singleton==null时不为null,则返回singleton。但此时singleton并还没初始化完毕,线程B访问的将是个还没初始化完毕的对象。当声明对象的引用为volatile后,伪代码的2、3的重排序在多线程中将被禁止!

静态内部类模式

public class Singleton {

private Singleton(){

}

public static Singleton getSingleton(){

return Inner.instance;

}

private static class Inner {

private static final Singleton instance = new Singleton();

}

}

推荐理由:

实现代码简洁。和双重检查单例对比,静态内部类单例实现代码真的是太简洁,又清晰明了。

延迟初始化。调用getSingleton才初始化Singleton对象。

线程安全。JVM在执行类的初始化阶段,会获得一个可以同步多个线程对同一个类的初始化的锁。

如何实现线程安全?

线程A和线程B同时试图获得Singleton对象的初始化锁,假设线程A获取到了,那么线程B一直等待初始化锁。线程A执行类初始化,就算双重检查模式中伪代码发生了重排序,也不会影响线程A的初始化结果。初始化完后,释放锁。线程B获得初始化锁,发现Singleton对象已经初始化完毕,释放锁,不进行初始化,获得Singleton对象。

在涉及到反射和序列化的单例中,建议使用下文的枚举类型模式。

其他类型的单例模式

懒汉模式(多线程不安全)

public class Singleton {

private static Singleton instance;

private Singleton (){}


public static Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}

饿汉单例模式(多线程安全)

public class Singleton {

private static Singleton instance = new Singleton();

private Singleton (){}

public static Singleton getInstance() {

return instance;

}

}

饿汉模式的线程安全同样通过类加载解决同步问题,但没有达到懒加载目的。(这里非常感谢之初z-chu的指正)

枚举单例模式(多线程安全)

public enum Singleton {

INSTANCE;


public void doSomething(){

//todo doSomething

}

}

在Joshua Bloch大神的《Effective Java》是推荐该方法的。虽然线程安全,在实际开发中,还没有被广泛采用。因为太过简洁以致于可读性较差,还没有在实战中被广泛推广。枚举单例模式的线程安全同样利用静态内部类中讲到类初始化锁。枚举单例模式能够在序列化和反射中保证实例的唯一性。

应用场景:

1.网站的计数器

2.应用程序的日志应用

3.数据库连接池

4.读取配置文件中的类

5.application

6.pask manager

总结

在实际工作中,单例的使用还是比较常见的,在几种实现方式中,双重检测机制、静态内部类、枚举方式都是比较推荐。

以上就是这篇文章的全部内容了,希望能对铁子们有帮助和收获。如果觉得文章有用,喜欢这篇文章的铁子们可以点点赞和关注,也可以分享出去让更多的人看见,一起努力一起进步! 文章持续更新,也可以评论出你想看哪一块技术。铁子们的支持是我的动力,创作离不开铁子们的支持,在此先感谢大家!创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章见。

© 著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务


喜欢的朋友记得点赞、收藏、关注哦!!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 18:22:39

AMESIM联合STAR CCM+实现单体电芯热仿真模型案例探究

电池热管理仿真,AMESIM联合STAR CCM电芯热仿真模型案例 此模型为单体电芯热仿真,非系统PACK热仿真,注意 AMESIM实现部分:基于二阶等效电路模型计算产热功率,模型包含完整的二阶等效电路模型参数,可根据需求…

作者头像 李华
网站建设 2026/4/16 11:58:40

AUTOENV 论文通俗解释:AI 代理如何在不同“世界”里学习?

AUTOENV:自动生成环境框架,助力跨环境代理学习测量 今天,我想和大家介绍一篇发表于arXiv的论文:《AUTOENV: Automated Environments for Measuring Cross-Environment Agent Learning》。这篇论文由香港科技大学(广州校…

作者头像 李华
网站建设 2026/4/16 3:52:00

测试大神必备技能,功能测试的链接测试你们都会了吗?

本章节主要讲解“软件功能测试的链接测试”的内容,功能测试主要是软件测试系统的业务逻辑是否正确,测试每个功能是否正确,但测试过程中不能仅仅对客户端的功能进行测试,而且需要考虑Web 系统的整个体系架构。功能测试主要从链接、表单、Cookies、设计语言和数据库五个方面进…

作者头像 李华
网站建设 2026/4/16 9:49:18

顺德双皮奶丝滑到挑战味觉极限?

有着中国最具地道烟火气息的高铁可,直达的美食旅游城市,以舌头当向导,每年去开启探索一座城,既能领略当地风土人情,还能好好享受舌尖上的盛宴,这就是美食旅行最叫人动心的意义。 顺德是厨出凤城的美食胜地…

作者头像 李华
网站建设 2026/4/16 13:44:26

原神自动化助手:解放双手的智能游戏伴侣

原神自动化助手:解放双手的智能游戏伴侣 【免费下载链接】genshin_impact_assistant 原神小助手 Genshin Assistant (CN/EN) | 自动战斗,秘境,领日常,半自动委托 项目地址: https://gitcode.com/GitHub_Trending/ge/genshin_impact_assistant 还在为原神中重…

作者头像 李华
网站建设 2026/4/16 13:44:48

SpringBoot 集成 Spring AMQP + RabbitMQ 一文搞定多种工作模式(点对点、工作队列、发布订阅、路由、主题、RPC、死信队列)与各种自定义配置详解

SpringBoot 集成 Spring AMQP RabbitMQ 一文搞定多种工作模式&#xff08;点对点、工作队列、发布订阅、路由、主题、RPC、死信队列&#xff09;与各种自定义配置详解 文中代码见 Don212 一、快速开始 1、在 Spring Boot 项目中引入一个依赖 <!-- Starter for using Spri…

作者头像 李华