单例模式
为什么要使用单例?
单例设计模式:一个类只允许创建一个对象(或者实例)
对象实例需求为唯一性
如何实现一个单例?
实现单例需要关注点:
- 构造函数私有化,这样才能防止外部通过new进行实例化
- 考虑对象创建时的线程安全问题
- 考虑是否支持延迟加载
- 考虑 getInstance() 性能是否高(是否加锁)
实现方式
1. 饿汉式
public class Singleton {
private static final Singleton instance = new Singleton();
// 构造函数私有化
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
优点:实现简单
缺点:非线程安全
2. 懒汉式
public class Singleton {
private static final Singleton instance;
// 构造函数私有化
private Singleton() {
}
public synchronized static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:保证了线程安全
缺点:加锁导致并发度不高,性能有损失
3. 双重检测
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;
}
}
既保证了线程安全,又支持懒加载
4. 静态内部类
public class Singleton {
private Singleton() {}
private static class SingletonHolder{
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
既保证线程安全,又支持懒加载
5. 枚举
public enum Singleton {
INSTANCE;
}
通过Java枚举类型的本身特性来保证了实例创建的线程安全和实例的唯一性