目录
一、单例模式的定义和理解
定义:某个类只有一个实例,并且提供一个全局访问点。(类 -- 一个实例 -- 一个全局访问点)
类型:创建型模式
理解:
整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,显然,这种方式简化了在复杂环境下的配置管理。
特别地,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。事实上,这些应用都或多或少具有资源管理器的功能。例如,每台计算机可以有若干个打印机,但只能有一个 Printer Spooler (单例) ,以避免两个打印作业同时输出到打印机中。再比如,每台计算机可以有若干通信端口,系统应当集中(单例) 管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态。
综上所述,单例模式就是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种方法。
使用场景:
当系统中只需要一个实例对象或者系统中只允许一个公共访问点,除了这个公共访问点外,不能通过其他访问点访问该实例时,可以使用单例模式。
- 有状态的工具类对象;
- 频繁访问数据库或文件的对象;
优缺点
- 节约系统资源、提高了系统效率,同时也能够严格控制客户对它的访问。
- 也许就是因为系统中只有一个实例,这样就导致了单例类的职责过重,违背了“单一职责原则”,同时也没有抽象类,所以扩展起来有一定的困难。
单例模式的注意事项
- 在使用单例模式时,我们必须使用单例类提供的公有工厂方法得到单例对象,而不应该使用反射来创建,否则将会实例化一个新对象。
- 此外,在多线程环境下使用单例模式时,应特别注意线程安全问题。
1、1单例模式及其单线程环境下的经典实现
1、介绍一下类图
- 类图三部分,依次是类名、属性、方法;
- <<……>>中的信息为注释信息;
- 修饰符
| 修饰符 | 类图中的符号 |
| private | - |
| protected | # |
| public | + |
| 包可见 | 啥都没有 |
- 带下划线的属性或方法代表是静态的。
单例模式的类图如下,这表明单例模式的类具有三个属性:
- 私有的构造方法;
- 指向自己实例的私有静态引用(-Singleton singleton);
- 以自己实例为返回值的公有静态方法(+Singleton getInstance())(一个全局访问点)。

2、单线程下单例模式的两种实现方式
理解概念:在 类加载 中的 立即加载 和 延迟加载
- 立即加载:在类加载初始化的时候主动创建实例;(一开始就有危机意识)
- 延迟加载:等到真正使用的时候才去创建实例,不用时不去主动创建。(火烧眉毛了才动)
基于这两种不同的理念,在单线程下,单利模式也就有两种相应的实现方式:
- 饿汉单例 (基于立即加载):在单例类被加载时候,就实例化一个对象,并将其交给自己的引用;
- 懒汉单例 (基于延迟加载):只有在真正使用的时候才会实例化一个对象并交给自己的引用。
从速度和反应时间角度来讲,饿汉式(又称立即加载)要好一些;从资源利用效率上说,懒汉式(又称延迟加载)要好一些。
饿汉单利模式如下:
/ 饿汉单例(立即加载)
public class Singleton1 {
// 指向自己实例的私有静态引用,主动创建
private static Singleton1 singleton1 = new Singleton1();
// 私有的构造方法
private Singleton1(){}
// 以自己实例为返回值的静态的公有方法,静态工厂方法
public static Singleton1 getSingleton1(){
return singleton1;
}
}
类加载的方式是按需加载,且加载一次。因此,在上述单例类被加载时,就会实例化一个对象并交给自己的引用,供系统使用;而且,由于这个类在整个生命周期中只会被加载一次,因此只会创建一个实例,即能够充分保证单例。
懒汉单例模式如下:
// 懒汉式单例
public class Singleton2 {
// 指向自己实例的私有静态引用
private static Singleton2 singleton2;
// 私有构造方法
private Singleton2(){}
// 以自己实例为返回值的静态公有方法,静态工厂方法
public static Singleton2 getSingleton2(){
// 被动创建,在真正需要使用时才去创建
if (singleton2 == null) {
singleton2 = new Singleton2();
}
return singleton2;
}
}

本文深入解析单例模式的定义、作用及其实现方式,包括单线程与多线程环境下的经典实现,如饿汉式与懒汉式单例。探讨其在资源管理中的应用,如线程池、缓存等,以及单例模式的优缺点和注意事项。
532

被折叠的 条评论
为什么被折叠?



