论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
软件与程序人生
›
DevOps与敏捷开发
›
单例计划模式
单例计划模式
饭宝
论坛元老
|
2025-1-5 05:57:55
|
显示全部楼层
|
阅读模式
楼主
主题
1039
|
帖子
1039
|
积分
3117
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
在软件开发的广阔范畴中,我们常常会碰到这样的场景:某些类在整个应用程序中只需要一个实例存在。比方,数据库连接池需要确保整个体系中只有一个连接池实例,以制止资源的浪费和管理的混乱;日志记载器也通常只需要一个实例,确保日志记载的一致性和准确性。单例模式就是为解决这类问题而生的,它是一种创建型计划模式,保证一个类仅有一个实例,并提供一个全局访问点。
一、单例模式的定义与特点
1.1 定义
单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。这意味着无论在应用程序的哪个部门请求该类的实例,得到的都是同一个对象。
1.2 特点
唯一性
:在整个应用程序生命周期内,该类只有一个实例存在。
全局访问
:提供一个全局的静态方法或属性,用于获取这个唯一实例,方便在程序的任何地方进行访问。
二、单例模式的实现方式
2.1 饿汉式单例
饿汉式单例在类加载时就立即创建实例,代码如下:
public class EagerSingleton {
// 类加载时就创建实例
private static final EagerSingleton instance = new EagerSingleton();
// 私有构造函数,防止外部实例化
private EagerSingleton() {}
// 提供全局访问点
public static EagerSingleton getInstance() {
return instance;
}
}
复制代码
饿汉式单例的优点是实现简单,在类加载时就创建实例,保证了实例在多线程情况下的唯一性。缺点是如果该单例对象在整个应用程序中使用频率不高,会造成资源浪费,由于在类加载时就创建了实例,而不管是否真的需要。
2.2 懒汉式单例(线程不安全)
懒汉式单例在第一次使用时才创建实例,代码如下:
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
// 第一次调用时创建实例
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
复制代码
懒汉式单例的优点是耽误实例化,只有在真正需要时才创建实例,节省了资源。但缺点是在多线程情况下,可能会创建多个实例,不具备线程安全性。比方,当两个线程同时判断 instance 为 null 时,它们都会创建一个新的实例,导致违反单例模式的唯一性原则。
2.3 懒汉式单例(线程安全 - 同步方法)
为相识决懒汉式单例的线程安全问题,可以在 getInstance 方法上添加 synchronized 关键字,使其成为线程安全的,代码如下:
public class LazySingletonSyncMethod {
private static LazySingletonSyncMethod instance;
private LazySingletonSyncMethod() {}
// 线程安全的获取实例方法
public static synchronized LazySingletonSyncMethod getInstance() {
if (instance == null) {
instance = new LazySingletonSyncMethod();
}
return instance;
}
}
复制代码
这种方式固然保证了线程安全,但由于 synchronized 关键字修饰了整个方法,在多线程情况下,每次调用 getInstance 方法都会进行同步操作,性能较低。特别是在高并发场景下,可能会成为性能瓶颈。
2.4 懒汉式单例(线程安全 - 双重查抄锁)
双重查抄锁机制结合了懒加载和线程安全,同时进步了性能,代码如下:
public class LazySingletonDoubleCheck {
private static volatile LazySingletonDoubleCheck instance;
private LazySingletonDoubleCheck() {}
public static LazySingletonDoubleCheck getInstance() {
if (instance == null) {
synchronized (LazySingletonDoubleCheck.class) {
if (instance == null) {
instance = new LazySingletonDoubleCheck();
}
}
}
return instance;
}
}
复制代码
这里使用了 volatile 关键字修饰 instance,确保了 instance 的可见性和禁止指令重排序。外层的 if (instance == null) 查抄是为了制止不须要的同步开销,只有当 instance 为 null 时才进入同步块。内层的 if (instance == null) 查抄是为了在多线程情况下确保只有一个实例被创建。
2.5 静态内部类实现单例
通过静态内部类实现单例,既保证了懒加载,又保证了线程安全,代码如下:
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {}
// 静态内部类
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}
// 提供全局访问点
public static StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
复制代码
这种方式利用了类加载机制的特性,只有在调用 getInstance 方法时,静态内部类 SingletonHolder 才会被加载,从而创建实例。由于类加载过程是线程安全的,以是这种方式既实现了懒加载,又保证了线程安全。
2.6 枚举实现单例
在 Java 中,枚举范例本身就保证了实例的唯一性,以是可以用枚举来实现单例,代码如下:
public enum EnumSingleton {
INSTANCE;
// 可以在这里添加其他方法和属性
public void doSomething() {
System.out.println("执行单例方法");
}
}
复制代码
使用枚举实现单例非常简便,并且天然支持序列化和反序列化,不会出现多个实例的问题。它是实现单例模式的一种推荐方式,尤其是在需要考虑序列化和反序列化场景下。
三、单例模式的应用场景
3.1 资源管理
数据库连接池
:在应用程序中,数据库连接是一种宝贵的资源。使用单例模式创建数据库连接池,可以确保整个应用程序共享一个连接池,制止频繁创建和烧毁数据库连接带来的性能开销。
线程池
:线程池同样需要保证唯一性,以合理管理和复用线程资源。通过单例模式,整个应用程序可以使用同一个线程池,进步线程的使用服从。
3.2 日志记载
日志记载器通常只需要一个实例,确保全部的日志记载都能按照统一的规则和格式进行处置惩罚。比方,在一个大型企业级应用中,各个模块的日志都通过同一个日志记载器实例进行记载,方便后续的日志分析和故障排查。
3.3 设置管理
应用程序的设置信息(如数据库设置、体系参数等)在整个应用程序中通常是共享的。使用单例模式创建一个设置管理器,负责读取和管理设置信息,可以保证设置的一致性和全局访问性。
四、单例模式的优缺点
4.1 优点
资源共享
:确保在整个应用程序中只有一个实例,方便资源的共享和管理,制止资源的重复创建和浪费。
全局访问
:提供了一个全局访问点,方便在应用程序的任何地方获取该实例,便于代码的编写和维护。
进步性能
:在某些场景下,如数据库连接池,使用单例模式可以减少资源的创建和烧毁次数,从而进步体系的性能。
4.2 缺点
测试困难
:由于单例模式的实例是全局唯一的,在单位测试中可能会导致测试结果的不可重复性。比方,在一个测试方法中修改了单例对象的状态,可能会影响到其他测试方法的执行结果。
不易扩展
:如果在后期需要对单例类进行扩展,可能会比较困难,由于单例模式的结构相对固定,修改可能会影响到整个应用程序中对该单例的使用。
可能导致内存泄漏
:如果单例对象持有对其他资源(如文件句柄、网络连接等)的引用,并且在应用程序竣事时没有准确释放这些资源,可能会导致内存泄漏。
五、结语
希望这篇文章可以或许帮助您更好地理解单例计划模式,并为您的编程实践提供指导。若实践有看法或疑问,欢迎评论区交流。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
饭宝
论坛元老
这个人很懒什么都没写!
楼主热帖
53基于java的资源博客论坛系统设计与实 ...
zotero+坚果云实现多pc端及iPad同步管 ...
Android——一个简单的记账本APP ...
天涯神贴合集500篇(2023最新) ...
需求:清空三个月前的操作日志,并生成 ...
面试官:@Configuration 和 @Component ...
nginx 常用指令配置总结
【分布式计算】学习笔记(期末复习) ...
Python潮流周刊#5:并发一百万个任务要 ...
PerfView专题 (第十一篇):使用 Diff ...
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
Oracle
物联网
快速回复
返回顶部
返回列表