单例模式的概念
- 一个类在内存中只允许创建一个实例,并且它们提供一个对自身的全局访问点。则该类可以被称为是一个单例的类,这种模式可以被称为单例模式。
单例模式的使用场景
- 系统的配置文件。比如数据源、服务的端口、黑白名单等信息以配置文件的方式进行管理,那么理论上同一个系统中应该只有一份该配置文件的实例。
- 日志类。通常日志类会以单例的形式实现,而不是每次执行日志操作时重新创建实例。
单例模式实现的原则
- 构造方法私有- 避免在该类的外部实例化
- 提供一个静态的访问方法,用于获取该类的唯一实例
单例模式经典实现方式
懒汉式(thread-unsafe)
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式(thread-safe)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
饿汉式(thread-safe)
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){ }
public static Singleton getInstance(){
return instance;
}
}
枚举(thread-safe)
public enum Singleton {
INSTANCE;
}
静态内部类(thread-safe)
public class Singleton {
private Singleton() { }
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
双重检查锁(thread-safe)
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null){
synchronized (Singleton.class){
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}