单例模式

单例模式

  • 饿汉式
public class SingleProto1 {

	// 程序加载即会创建对象
	private static SingleProto1 instance = new SingleProto1();
	
	// 防止被别人创建对象
	private SingleProto1(){
		
	}
	
	// 提供调用方获取对象的方法,保证拿到的是唯一的对象
	public static SingleProto1 getInstance(){
		return instance;
	}
}

如果不需要用到这个对象时,对象仍会存在内存中,浪费空间,浪费资源,所以出现了下面的懒汉式,即需要对象时再进行创建

  • 懒汉式
public class SingleProto2 {

	private static SingleProto2 instance = null;
	
	// 防止被别人创建对象
	private SingleProto2(){
	}
	
	// 提供调用方获取对象的方法,保证拿到的是唯一的对象
	public static SingleProto2 getInstance(){
		if(instance == null){
			return new SingleProto2();
		}else {
			return instance;
		}
	}
}

懒汉式使用时,如果出现多线程操作同一个对象,会出现线程安全问题,如图:

此时加上同步关键字即可:

这样的情况,又会有吹毛求疵的人会说:万一你创建对象之前有很多的逻辑代码需要处理该怎么办,此时锁需要进行细化,就仅仅需要在需要加锁的地方进行加锁,所以出现下面的代码:

此时仍然会出现线程安全问题,当两个线程先后进入到null条件时,一个线程创建完对象后,另一个线程也在null条件中,此时锁释放拿到锁也可以创建新的对象,就不能保证对象是单例的。

所以出现了DCL,即Double Check Lock

此时最值得注意的是,关乎多个线程操作单例单例对象时,需要在对象前加volatile关键字,保证线程间的可见性,并且避免指令的重排从而达到线程安全

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值