设计模式-单例模式
# 设计模式-单例模式
单例模式较为简单和理解,可以相当于一个系统只有这么一个核心部分。比如人只有一个心脏、世界只有一个太阳等。通过单例模式可以确保系统中的一个类只有一个实例而且该实例易于被外接访问,从而方便对实例个数进行控制,节约系统资源。
目的:
确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。
适用环境:
- 系统只需要一个实例对象,比如生产唯一序列号等。
- 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
优点:
- 单例模式提供了对唯一实例的受控访问。
- 由于在系统内存中只存在一个对象,因此可以节约资源,对于一些需要频繁创建和销毁的对象,单例模式可以提高系统的性能。
缺点:
- 单例模式没有抽象层,对单例类的扩展有很大困难
- 没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
# 案例
# 简单实现单例模式
public class Singleton {
/**
* 静态私有成员变量
*/
private static Singleton instance = null;
/**
* 私有构造方法
*/
private Singleton() {}
/**
* 静态公有工厂方法,返回唯一的实例
*/
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
public class SingletonDemo {
public static void main(String[] args) {
Singleton instance01 = Singleton.getInstance();
Singleton instance02 = Singleton.getInstance();
// 判断两个对象是否相同
if(instance01 == instance02) {
System.out.println("两个对象是相同实例");
} else {
System.out.println("两个对象是不同实例");
}
}
}
// 两个对象是相同实例
# 几种单例模式实现
上面的这一种单例模式实现叫做懒汉式
,但是这种实现的最大问题就是不支持多线程,因为没有加锁synchronized
懒汉式,线程安全:
public class Singleton {
private static Singleton instance = null;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
饿汉式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
- 优点:没有加锁,执行效率会提高。
- 缺点:类加载时就初始化,浪费内存。
# 双检锁/双重校验锁
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
这种方式采用双锁机制,安全且在多线程情况下能保持高性能。getInstance()
的性能对应用程序很关键。
为什么要双重加锁
当成功获取到锁后,检查实例状态,避免 “陆续获取到锁” 导致的重复实例化
# 参考
上次更新: 2024/06/29, 15:13:44