适用场景:
-
需要生成唯一序列的环境
-
需要频繁实例化然后销毁的对象。
-
创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
-
方便资源相互通信的环境
饿汉式
特点:线程安全,调用效率高,但是不能延时加载
public class HungrySingle {
//实例化
private static final HungrySingle hs = new HungrySingle();
//私有化构造器
private HungrySingle(){
}
//创建静态工厂方法 ,让外部可以获取实例
public static HungrySingle getInstance(){
return hs;
}
}
懒汉式
特点:线程安全,调用效率不高,但是能延时加载
public class LazySingle {
//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)
private static LazySingle ls;
// 私有化构造器
private LazySingle(){
}
//方法同步,调用效率低
// 创建静态工厂方法 ,让外部可以获取实例
public static synchronized LazySingle getInstance(){
if (ls == null){
ls = new LazySingle();
}
return ls;
}
}
DCL懒汉式
DCL:Double CheckLock,也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,不建议使用),是在懒汉式单例上发展而来
public class DCLLazySingle {
private volatile static DCLLazySingle instance;
//私有化构造器
private DCLLazySingle(){
}
//静态工厂方法,双重锁判断机制
public static DCLLazySingle newInstance(){
if (instance == null){
synchronized (DCLLazySingle.class){
if (instance == null){
instance = new DCLLazySingle();
}
}
}
return instance;
}
}
静态内部类模式
特点:线程安全,调用效率高,可以延时加载
public class InnerSingle {
//静态内部类
private static class InnerClassInstance{
private static final InnerSingle instance = new InnerSingle();
}
//私有化构造器
private InnerSingle(){
}
//静态工厂方法
public static InnerSingle getInstance(){
return InnerClassInstance.instance;
}
}
枚举类
特点:线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用
public class EnumSingle {
//私有化构造器
private EnumSingle(){
}
//使用枚举
private static enum Single{
INSTANCE;
private EnumSingle es;
//JVM会保证此方法绝对只调用一次
private Single(){
es = new EnumSingle();
}
public EnumSingle getInstance(){
return es;
}
}
//静态工厂方法
public static EnumSingle getInstance(){
return Single.INSTANCE.getInstance();
}
}
如何选择 ???
-
单例对象占用资源少,不需要延时加载时:枚举 好于 饿汉
-
单例对象占用资源多,需要延时加载时:静态内部类 好于 懒汉式