Java单例模式详解(五种实现方式)

1、什么是单例模式?

Java单例模式是一种设计模式,用于确保一个类只有一个实例,并提供全局访问点以获取该实例。它通常用于需要共享资源或控制某些共享状态的情况下。

例如:

一个日志记录器(Logger)。在一个应用程序中,可能有多个组件需要记录日志,但是我们希望只有一个日志记录器实例来避免重复创建和管理多个日志文件。使用单例模式,我们可以确保只有一个日志记录器实例存在,并且所有组件都可以共享该实例来记录日志。这样可以简化日志记录的管理,并确保日志信息的一致性。

2、实现方式

  • 懒汉式:再不会再类加载的时候就创建对象,要再调用方法时才创建对象,减少内存开销。
  • 饿汉式:再类加载的时候就实例化对象。

2.1同步方法调用创建实例(懒汉式)

当刚加载这个类时不会直接初始化person,只有调用getPerson()方法时才会构建唯一实例。这种方式能很好的保证多线程安全,但效率很低,因为大多数调用这个方法的时候是不需要同步的。

public class Person {
	private static Person person;
	//将构造器私有化,就无法从外部调用构造器构造对象
	private Person(){}
    
    //此时这个synchronized是保证线程安全
	public synchronized static Person getPerson() {
		if (person == null) {
			person = new Person();
		}
		return person;
	}
}

2.2双重校验锁方式加载对象实例(懒汉式)

这里我们用了两个判断,再第一个判断不通过时我们就没有用到同步代码块,这样相较于上一个实现方式提高效率。

public class Person {
	//此时要用volatile用于保证person = new Person()内部指令不排序
	private volatile static Person person;
	//将构造器私有化,就无法从外部调用构造器构造对象
	private Person(){}

	public  static Person getPerson() {
		if (person ==null){
			synchronized (Person.class){
				if (person == null){
					person = new Person();
				}
			}
		}
		return person;
	}
}

2.3静态变量加载对象实例(饿汉式)

对象唯一实例会随着这个类的加载就会被初始化出来,基于 classloader 机制避免了多线程的同步问题,但它再还没有使用这个对象时就被加载出来,有点浪费内存空间。

public class Person {
	private static Person person = new Person();
	//将构造器私有化,就无法从外部调用构造器构造对象
	private Person(){}

	public  static Person getPerson() {
		return person;
	}
}

2.4静态内部类实现单例模式(懒汉式)

这里用到了一个知识点,就是内部类不会随着外部类的加载而加载,而是再第一次使用到内部类后再加载初始化内部类。这样的机制实现了懒汉模式。我们使用了final修饰,也将其确定为单例模式。

public class Person {
	private static class PersonHolder {
		private static final Person INSTANCE = new Person();
	}
//将构造器私有化,就无法从外部调用构造器构造对象
	private Person (){}
	public static final Person getInstance() {
		return PersonHolder.INSTANCE;
	}
}

2.5 枚举实现单例模式(饿汉式)

这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}
相关推荐
WeiLai111224 分钟前
面试基础--Redis 缓存穿透、缓存击穿、缓存雪崩深度解析
java·redis·分布式·后端·缓存·面试·架构
wclass-zhengge24 分钟前
02C#基本结构篇(D1_基本语法)
开发语言·microsoft·c#
zctel24 分钟前
java中小型公司面试预习资料(二):Redis
java·redis·面试
hrrrrb25 分钟前
【C语言】数组篇
c语言·开发语言
爱吃烤鸡翅的酸菜鱼1 小时前
Java【网络原理】(3)网络编程续
java·运维·服务器·网络
蜡笔小新..2 小时前
R语言和RStudio安装
开发语言·r语言
ALPH_2 小时前
R语言的基础命令及实例操作
开发语言·数据分析·r语言·perl·r语言-4.2.1
咩咩觉主3 小时前
C# &Unity 唐老狮 No.6 模拟面试题
开发语言·unity·面试·c#·游戏引擎·唐老师
╰つ゛木槿5 小时前
Spring Boot 调用DeepSeek API的详细教程
java·spring boot·后端·deepseek
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧5 小时前
C语言_数据结构总结8:链式队列
c语言·开发语言·数据结构·链表·visualstudio·visual studio