单例模式(Singleton Pattern)是Java中最简单且常用的设计模式之一。常用的单例模式实现分两类,懒汉模式和饿汉模式。其中饿汉模式又分为双重锁检查以及内部静态类两种实现方式。那么,哪种是最优雅且性能最高的实现呢?
1. 青铜实现(恶汉模式)
```
public class Singleton {
//实例,使用类加载初始化,所以是线程安全
private static final Singleton INSTANCE = new Singleton();
//构造函数必须是私有的
private Singleton (){
}
//单例调用
public static Singleton getInstance() {
return INSTANCE;
}
}
```
这种实现方式简单,线程安全(类加载初始化),但由于在类初始化就加载所以容易产生垃圾,浪费内存。总结一句话就是,简单,安全但是不够优雅。
2. 黄金实现(懒汉模式+双重锁)
```
public class Singleton {
//volatile实例,保证线程可见性以及初始化的原子性
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;
}
}
```
双重锁校验(DCL即double checked locking)实现方式,线程安全,调用时构造,但实现复杂,容易出错。总结一句话就是,安全,优雅但不够简单。
3. 王者实现(静态内部类)
```
public class Singleton {
//静态内部类,只有显式调用才会加载
private static class SingletonFactory {
private static final Singleton INSTANCE = new Singleton();
}
//构造函数必须是私有的
private Singleton (){
}
//单例调用
public static Singleton getInstance() {
return SingletonFactory.INSTANCE;
}
}
```
静态内部类实现方式,简单,优雅(静态内部类只有在显式调用时才会加载),同时线程安全(ClassLoader的线程安全机制,ClassLoader的loadClass方法在加载类的时候使用了synchronized关键字)。
个人倾向于静态内部类实现方案,简单,安全而且优雅。
如何优雅的实现Java的单例模式