单例模式
所谓单例模式就是一个类只有一个实例。
注意点:
1、多线程之间并发考虑,保证只有一个实例创建
2、保证序列化和反序列化后依然只有一个实例
常用实现方式
1、饥饿模式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){
}
public static Singleton getInstance() {
return instance;
}
}
关键点
- 利用在类的加载过程中 ,static变量会初始化一次。先创建好一个实例
- 提供静态方法获取此实例
- 私有构造方法
优点
- 简单明了
- 可读性好
缺点
- 实例事先创建好,可能无效的占用内存空间,并未使用(一帮情况 既然用到了此类,很大可能也要要获取此实例的)
- 反序列化会创建多个实例
2、懒汉模式(双重检查(DCL))
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){
}
public static Singleton getInstance() {
if (instance== null) {
synchronized (Singleton.class) {
if (instance== null) {
instance= new Singleton();
}
}
}
return singleton;
}
}
关键点
- volatile关键字 防止CPU指令重排
- 静态方法多线程并发考虑加锁 且 双重检查
- 私有构造方法
优点
- 使用时才创建真正的实例 不浪费空间
缺点
- 代码实现稍复杂
- 不支持反序列化
3、懒汉模式(内部类实现)
public class Singleton {
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
关键点
- 静态内部类的静态变量
- 私有构造方法
优点
- 对比双重检查方式 代码跟简洁 高效
缺点
- 不支持反序列化
4、枚举类型实现单例
public enum Singleton {
INSTANCE;
public void doSomeThing() {
}
}
枚举本质就是一个类 extends Enum,本质还是一个类;且默认的构造方法是private的,JVM是禁止反射调用枚举的私有构造方法
基于枚举这些特点所以说 枚举是实现单例的最佳实践。
但可读性并不友好。
优点:即使反序列化依然只有一个实例!
总结:
1、不考虑序列化的情况 优先使用第1种 或 第3种
2、出于绝对的安全考虑 请使用 枚举方式

浙公网安备 33010602011771号