饿汉式
作用:保证一个类只有一个实例并且提供一个访问该实例的全局访问点
特点: 线程安全,比较常用,但容易产生垃圾,因为一开始就初始化
public class HungaryMan
{
//1.私有化构造器,如果不私有外面就可以new出多个对象
private HungaryMan()
{
}
//2.类初始化的时候就立即加载该对象
private static HungaryMan instance = new HungaryMan();
//3.提供获取该对象的方法
public static HungaryMan getInstance()
{
return instance;
}
}
懒汉式
特点:线程不安全,延迟初始化
public class LazyMan
{
//1.私有化构造器,如果不私有外面就可以new出多个对象
public LazyMan()
{
}
//2.类初始化的时候就并不立即加载该对象
private static LazyMan Instance;
//有多个线程的话,需要让他们排队,但效率较低
public static synchronized LazyMan getInstance()
{
//调用之前判断实例是否存在
if (Instance == null)
{
Instance = new LazyMan();
}
return Instance;
}
}
DCL懒汉式
public class DCLLazyMan
{
//1.私有化构造器,如果不私有外面就可以new出多个对象
public DCLLazyMan()
{
}
//2.类初始化的时候就并不立即加载该对象
//增加volatile关键字,避免指令重排
private volatile static DCLLazyMan Instance;
//有多个线程的话,需要让他们排队,但效率较低
public static DCLLazyMan getInstance()
{
/**
* 首先去判断是否存在该对象的实例,判断为空就去看其他锁是否存在,最后确认不存在就去返回该对象
* 的实例
*/
//调用之前判断实例是否存在
if (Instance == null)
{
synchronized (DCLLazyMan.class)//把锁的范围锁的更精细
{
if (Instance == null)
{
Instance = new DCLLazyMan();
}
}
}
return Instance;
}
静态内部类改进饿汉式单例
public class StaticHungaryMan
{
public StaticHungaryMan()
{
}
private static class InnerClass
{
private static final StaticHungaryMan instance = new StaticHungaryMan();
}
public static StaticHungaryMan getInstance()
{
return InnerClass.instance;
}
}
上面四种单例模式均可以被反射破坏掉。
枚举单例
public class StaticHungaryMan
{
public StaticHungaryMan()
{
}
private static class InnerClass
{
private static final StaticHungaryMan instance = new StaticHungaryMan();
}
public static StaticHungaryMan getInstance()
{
return InnerClass.instance;
}
}
反射无法破坏,所以枚举单例安全性最高,但是实用性较低!
Author By 朝花不迟暮
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16464.html