一、定义
确保一个类只有一个实例,并提供一个全局的访问点。
二、使用场景
- 配置文件加载
- 序列号产生器
- 计数器
- ...
三、实例
单例模式有多种实现方式,常见的有“懒汉式”、“懒汉式(线程安全)”、“饿汉式”、“双重检查加锁法”、“静态内部类”。
在实际生产环境中,我们一般使用”双重检查加锁法“,其他实现方式一般不太使用。
下面是常用的 “双重检查加锁法” 的写法。
源码:gitee
/**
* 双重检查加锁法
*/
public class SingFactory implements Serializable {
// volatile关键字
// 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
// 2)禁止进行指令重排序
public volatile static SingFactory singleton = new SingFactory();
// 1、确保一个类只有一个实例
// 私有化构造函数,禁止外部进行创建对象
private SingFactory() {
// 防止使用 反射 获取构造方法
// 在构造器中加个逻辑判断,多次调用抛出异常
if (singleton != null) {
throw new RuntimeException();
}
}
// 2、并提供一个全局的访问点
// 使用静态方法进行获取对象,如果对象不存在,则进行加锁创建对象
public static SingFactory getInstance() {
if (singleton == null) {
synchronized (SingFactory.class) {
if (singleton == null) {
singleton = new SingFactory();
}
}
}
return singleton;
}
// 防止反序列化产生新的 SingFactory 对象
// 反序列化定义该方法,则不需要创建新对象
private Object readResolve() throws ObjectStreamException {
return singleton;
}
}