设计模式 -- 单例模式
单例模式:
目的:
确保系统中一个类只产生一个实例。
好处:
1.对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。
2.由于new操作的次数减少,因而对系统内存的使用频率也会降低,减轻GC压力,缩短GC的停顿时间。
单例模式的角色:
角色 | 作用 |
单例类 | 提供单例的工厂,返回单例 |
使用者 | 获取病使用单例类 |
代码实现:
public class Singleton { private Singleton(){} private static Singleton instance = new Singleton(); public static Singleton() { return instance; } }
上述的单例实现,可以确保一个系统中只有一个实例。但是却有另外一个问题,就是由于实例成员变量是static,因此JVM在加载单例类时,单例对象就会被创建。
如果单例类此时还承载着其他用途,那么不管这个单例类是否会被用到,都会初始化这个单例变量。
如下的代码:
public class Singleton { private Singleton() { System.out.println("Singleton is create"); } private static Singleton instance = new Singleton(); private static Singleton getInstance() { return instance; } /** * 模拟单例类中扮演其他角色 */ public static void createString() { System.out.println("createString in Singleton"); } }
当在main方法中尝试调用createString方法时,会看到私有构造中的打印语句被输出了,说明在调用createString时实例化了instance变量。
这也许并不是你想要的结果,如果我们希望对象在使用时再被创建,那么就需要引入延时加载的机制:
public class LazySingleton { private LazySingleton(){ System.out.println("LazySingleton is create"); } private static LazySingleton instance = null; public static synchronized LazySingleton getInstance() { if(null == instance) { instance = new LazySingleton(); } return instance; } public static void createString() { System.out.println("createString"); } }
上述的代码实现了延时加载,同时在获取实例的方法中加入了synchronized关键字,为了确保在多线程环境下的线程安全问题。
但是同样由于synchronized关键字,它的耗时也要远远多于第一种。
为了延时加载,而降低了系统性能有点得不偿失。所以在此改进单例代码:
public class Singleton { private Singleton(){} private static class SingletonHolder { private static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }
上述的代码采用内部类的形式来实现单例代码,首先,单例对象在内部类中进行实例化,而内部类只有在调用getInstance方法时才会被调用一次。从而实现了延时加载。
而且由于java内部类的加载是线程安全的,同时也解决了多线程下单例的问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一文彻底搞懂 MCP:AI 大模型的标准化工具箱
· 电商平台中订单未支付过期如何实现自动关单?
· 用 .NET NativeAOT 构建完全 distroless 的静态链接应用
· 为什么构造函数需要尽可能的简单
· 探秘 MySQL 索引底层原理,解锁数据库优化的关键密码(下)
· 短信接口被刷爆:我用Nginx临时止血
· 面试官:如果某个业务量突然提升100倍QPS你会怎么做?
· .NET 平台上的开源模型训练与推理进展
· 聊聊智商税:AI知识库
· 深感一无所长,准备试着从零开始写个富文本编辑器