一、单例模式的概念和应用
1、单例模式能解决的问题: 保证对象使用的时候,只有唯一的一个对象
2、单例模式的概念: 单利 模式就是在对象使用中,只有一个对象。基本方法就是提供一个静态访问方法,保证只有一个实例,不会重复创建
3、使用单例模式的好处: 在某些特定情况下可以节省资源,避免性能损失
4、单例模式的应用: 在非关系型数据库中,底层的连接池都会用到
二、两种单例设计模式
1、饿汉模式
在类加载时完成实例化 可通过静态常量 或 静态代码块实现 实现简单但是如果未对该资源进行使用造成资源的浪费(空间换时间的概念)
第一步:私有化构造器,防止外部创建对象
第二步:在内部实例化对象,并static对象,可以被static方法调用
第三部:在外部暴露方法,就可以在外部直接方法
//饿汉式单利设计模式
public class Single01 {
//第一步构造器的私有化,防止多次的创建,造成内存的的浪费
private Single01() {
}
//在内部实例化一个对象,为了能够在静态方法中,使用,需要将对象静态化
private static Single01 single01 = new Single01();
//第二步,在外暴露一个方法,就是在外面可以直接执行的操作
public static Single01 getInstance() {
return single01;
}
}
2、懒汉式(实际开发中常用)
1、在需要使用时,调用方法实例化 要保证多线程情况下的安全性和性能,存在线程安全的问题(时间换空间的概念)
2、因为有线程的不安全问题,所以我们需要给方法上锁,但是加锁是个重量级的操作,会带来很大的性能开销,所以我们需要用到引入一种概念就是双重校验锁的方式,来解决线程不安全的问题
3、还有一个创建对象的时候不是一个原子性的操作。
创建对象的流程:
1、分配对象内存,2、初始化对象,3、对象指向给刚刚的地址。
JVM可能不是按这个流程走的,而是随机走,就有可能造成对象创建的时候出现空指针现象
所以我们要设置指令重排的关键字Volatile,加在对象上(禁止指令重排序)。
/**
* 演示懒汉式的代码
* @author 西西
* 懒汉式,当使用到这个方法时,才会创建这个对象,没有使用时不回创建
* 防止内存资源的浪费
*/
public class Single02 {
//首先还是要进行构造器的私有化
private Single02() {
}
//定义一个静态属性对象
private static volatile Single02 single02;
public static Single02 getInstance() {
//判断如果single02对象是空的,就会被创建,外部的if就是为了避免每次线程过来都要持有锁,提高效率
if (single02 == null) {
//加锁,防止多线程的问题
synchronized (Single02.class) {
if (single02 == null) {
single02 = new Single02();
}
}
}
return single02;
}
}
单例模式注意事项和细节说明
1、单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能
2、当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new3、建议不要使用反射进行设计单例模式,因为反射可以暴力破坏单例模式