单例模式简单总结
简单的概念:通过单例模式的方法创建的类,在一个进程中仅有一个对象,这一个模式的目的是使得一个类的实例对象在系统中仅有一个,因此需要用一种只允许生成对象类的唯一实例的机制
单例模式在JAVA实现的方法大概有以下5种方式
1、饿汉式
饿汉式优点:一个类只能加载一次,线程安全,在加载时提前创建好对象,调用时反应快
饿汉式缺点:对象提前创建好,需要占用内存
2、懒汉式
懒汉式优点:在第一次调用getInstance()时,才进行对象初始化,如不需要则不创建,节省内存空间
懒汉式缺点:第一次掉用时,需要创建对象,响应速度慢,有线程安全的风险,并发的情况下有可能创建多个实例
3、双重检查锁定模式
双重检查锁定模式优点:安全,在多线程情况下保证线程安全,且不会提前创建对象,第一个if避免了所有线程都去抢占锁,提高了并发效率,第二个再次判断对象是否为空,防止抢占到锁之后已经有其他对象成功创建了对象
双重检查锁定模式缺点:由于JVM执行程序时,会对字节码指令进行优化,导致发生指令重排序,有可能会出现对象不存在但是 singleton !=null的情况下,返回了错误对象,需要加volatile指令防止重排序
Singleton singleton = new Singleton() 其实包含了三个步骤
1.给 Singleton实例对象分配内存空间;
2.调用 Singleton 的构造函数进行初始化;
3.将创建的对象所在地址指向局部变量singleton
正常的执行顺序是 123,那么就没有问题,有时候会发生指令重排序 执行顺序变成132.那么就会发生我上面所说的对象不存在但是 singleton !=null 的情况发生
4、静态内部类模式
静态内部类模式优点:
支持延迟加载,外部类被加载时,不会加载内部类
根据一个类只能加载一次特性,是线程安全的
不需要加锁
静态内部类模式缺点:需要多维护一个类,就需要多加载一个类,浪费内存
5、枚举模式(推荐使用)
优点:单项的枚举模式是一个天然的单例模式,实现简单,是一个真正的单例模式(不可以通过反射生成其他实例,其他模式都可以通过反射生成额外的实例),线程安全