单例模式的由来:多个线程操作不同实例对象。多个线程要操作同一对象,要保证对象的唯一性
解决问题:实例化过程中只实例化一次
单例模式:有一个实例化的过程(只有一次),产生实例化对象 new提供返回实例对象的方法
单例模式分类:
饿汉模式:
线程的安全性、性能、懒加载(lazy )
public class HungerySingleton {
//加载的时候就产生的实例对象
private static HungerySingleton instance=new HungerySingleton();
private HungerySingleton(){
}
//返回实例对象
public static HungerySingleton getInstance(){
return instance;
}
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
new Thread(()->{
System.out.println(HungerySingleton.getInstance());
}).start();
}
}
}
线程安全性:在加载的时候已经被实例化,所以只有这一次,线程安全的。初始化通过JVM ClassLoade
懒汉式:
性能比较好
懒加载
线程的安全性
问题:因为指令重排一起空指针异常
这里本人是通过枚举的方式实现的懒加载单例模式,
参考代码
public class EnumSingletonDemo {
private EnumSingletonDemo(){
}
//延迟加载
private enum EnumHolder{
INSTANCE;
private static EnumSingletonDemo instance=null;
private EnumSingletonDemo getInstance(){
instance=new EnumSingletonDemo();
return instance;
}
}//懒加载
public static EnumSingletonDemo getInstance(){
return EnumHolder.INSTANCE.instance;
}
}
Holder 声明类的时候,成员变量中不声明实例变量,而放到内部静态类中,
public class HolderDemo {
private HolderDemo(){
}
private static class Holder{
private static HolderDemo instance=new HolderDemo();
}
//懒加载
//synchronized
//<init>
public static HolderDemo getInstance(){
return Holder.instance;
}
//广泛的一种单例模式
}
实现单例方式有很多种,这里就不一一赘述了,反正我觉得这两种懒加载模式相对来说是最好的了
总结:
单例模式:实例化过程只能有一次,并且提供返回对象的实例
饿汉模式:初始化加载
懒汉模式:调用的时候加载