单例设计模式
单例设计模式是一种常见的软件设计模式,其核心思想是确保一个类只有一个实例,并提供一个全局访问点来访问该实例。
在实现单例模式时,通常需要考虑以下几点:
- 私有构造函数:将类的构造函数定义为私有,避免外部实例化。
- 静态成员变量:在类的内部创建一个静态的成员变量来保存该类的唯一实例。
- 静态方法:提供一个静态方法来获取类的实例。
- 线程安全性:保证多线程环境下线程安全。
单例模式包括懒汉式和饿汉式两种创建模式。
饿汉式
优点:
- 实现简单,线程安全
- 类加载时完成实例化,避免了线程安全问题
缺点:在类加载时就初始化,可能会浪费内存。
静态变量
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
静态代码块
public class Singleton {
private static Singleton instance;
static {
instance = new Singleton();
}
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
枚举
public enum Singleton {
INSTANCE;
// 提供获取单例对象的方法
public static Singleton getInstance() {
return INSTANCE;
}
}
懒汉式
懒加载,需要时才会进行实例化
线程不安全
在多线程环境下会出现线程安全问题
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
线程安全——sychronized锁
每次获取实例都需要同步操作,性能较低
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
线程安全——双重检查锁
public class Singleton {
// volatile关键字确保多线程正确处理instance的可见性和禁止指令重排序优化
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一次检查实例是否存在,如果不存在才进入下面的同步块
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查实例是否存在,如果不存在才创建实例
instance = new Singleton();
}
}
}
return instance;
}
}
线程安全——静态内部类
public class Singleton {
private Singleton() {}
// 静态内部类,类加载的时候不会初始化,只有调用getInstance()方法时才会初始化
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}