单例模式的几种实现方式

单例模式介绍

属于设计模式的一种,不是Java独有,一种类型,为其他调用方提供本类的实例对象,始终都是同一个对象

使用场景

使用jdbc操作数据库的时候,此时数据库连接可以通过数据库连接池来获取,为了防止出现多个对象操作数据库,产生并发执行事务,就会产生一系列的问题,这里最好的就是让操作直接串行化,就可以避免这所有的问题了,那怎么串行化,只有一个对象来进行操作,肯定也就只能依次操作了,

实现方式

设计思想就是:
1)私有的构造方法(外部就不能new了,否则就不是同一个对象了)
2)内部构造同一个对象,提供开发的方法给外部使用

private 当前类(){}
public static 当前类型 getInstance(){
return 内部new的同一个对象
}

饿汉式(线程安全)

class Singleton {
	private static Singleton instance = new Singleton();
	private Singleton() {}
	public static Singleton getInstance() {
		return instance;
	}
}

类加载的时候就初始化了,就存在一点缺点
1.还没有使用,就浪费了内存空间;
2.new对象(没有执行类加载,会先执行,再执行成员变量+实例代码块+构造方法),可能抛出异常,下一次使用就使用不了了。

懒汉式(线程不安全)

class Singleton {
	private static Singleton instance = null;
	private Singleton() {}
	public static Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}

instance = new Singleton();可以分解成三行字节码指令
是对共享变量的多行指令操作,就不具有线程安全,当初始化时,多个对象同时判定为null,就会都进入创建,这里就是线程不安全的。

静态同步方法+懒汉式(线程安全)

class Singleton {
	private static Singleton instance = null;
	private Singleton() {}
	public synchronized static Singleton getInstance() {
		if (instance == null) { //1
			instance = new Singleton();  //2
		}
		return instance;  //3
	}
}

效率比较差,因为这里把下面的三个条都加锁了,但是这里的1和3是具有原子性的,可以只需要保证可见性,就是线程安全的,但是因为这里的创建只有一次,使用是多次的,所以这里效率是不高的。

双重校验锁(线程安全)

class Singleton {
	private static volatile Singleton instance = null;
	private Singleton() {}
	public static Singleton getInstance() {
		if (instance == null) {
			synchronized (Singleton.class) {
				if (instance == null) {
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

这里就将上述所说的加上了volatile关键字,保证了可见性,所以执行创建完成之后的代码,就不需要加锁的,
这里第二个 if 存在的原因是:申请锁失败的线程,再重新获取锁,执行代码时,如果没有再次判断,就会创建一个新的对象,也就不满足单例的概念了

1.初始化完成之后,不需要加锁,使用volatile修饰变量,保证可见性,能满足线程安全(代码本身就是原子性),这样就可以并发并行的执行,提高了执行效率
2.没有初始化完成时,创建对象需要加锁来保证线程安全
3.竞争锁失败的线程,还会执行同步代码,需要再次判断,保证只初始化一次
4,引用使用了volatile关键字,还有建立内存屏障,禁止指令重排序的功能(new 分解的三条指令)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值