本文参考《源码解析设计与实战》
1.饿汉式
public class Singleton{
private static final Singleton instance=new Singleton();
private Singleton(){}
public static Singleton getinstance(){
return instance
}
}
优点:可以创建唯一实例
缺点:1.可以通过反序列化创建实例
2.加载类时就会被实例化,浪费资源
总结:可以使用
2.懒汉式
private static final Singleton instance;
private Singleton(){}
public static synchronized Singleton getinstance(){
if(instance==null){
instance=new Singleton();
}
return instance
}
}
优点:线程安全
缺点:第一加载反应慢 每次调用getInstance都要同步 造成不必要的开销
总结:这种模式一般不建议使用
3.Double Check Lock(DCL) 双重检查锁定
public class Singleton{
private static final Singleton instance=null;
private Singleton(){}
public static Singleton getinstance(){
if(instance==null){//避免不必要的同步
synchronized(Singleton.class){
if(instance==null){//创建实例
instance=new Singleton();
}
}
}
return instance
}
}
优点:1.资源利用率高
2.解决多余同步
3.线程安全
缺点:1.第一次加载反应慢
2.低于JDK6版本偶尔失败(极少,被称作双城检查失效)
3.可以通过反序列化创建实例
解决缺点3:在JDK1.5之后 将 private volatile static Singleton instance=null;可以确保单例的创建成功,但是volatile 会影响一定的性能,但是为了确保稳定性 牺牲这点还是值得的。
总结:一般满足需求
4.静态内部类单例模式
public class Singleton{
private Singleton(){}
private static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static calss SingletonHolder{
private static final Singleton sInstance=new Singleton();
}
}
优点:加载类是不会初始化单例,调用单例方法是才会被初始化
1.确保线程安全
2.保证单例对象唯一
缺点:可以通过反序列化创建实例
总结:推荐使用
5.枚举单例
public enum SingletonEnum{
INSTANCE;
}
优点:1.线程安全
2.创建单例成功
3.不会被反序列化创建实例
6.总结
无论以哪种形式实现单利模式,核心都是将构造函数私有化,然后通过静态方法获取唯一的实例,过程中要确保线程安全,防止反序列化造成再生实例等问题。使用单利模式时要结合项目本身,例如时候是复杂的开发环境,JDK版本是否过低一级单例对象的资源消耗等。(推荐方式3,4,5)