处理单例设计模式中懒汉式的安全问题过程

设计模式:解决某一类问题最行之有效的方式。Java中有23中设计模式。单例设计模式目的:解决一个类在内存中对象的唯一性。

解决方案:

1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象

2.还为了让其他程序可以访问该类对象,只好在本类中自定义一个对象

3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

以上三个步骤实现过程:

1.将构造函数私有化,

2.在类中创建一个本类对象,

3.提供一个方法,可以获取该对象

单力设计模式有两种模式:“饿汉式”和“懒汉式”。

饿汉式:类一经加载进内存就创建对象。如代码示例-1

代码示例-1

class Single
{
	private static final Single s = new Single();
	private Single(){}
	public static Single getInstance()
	{
		return s;
	}
}
懒汉式:类加载后没有创建对象,类调用getInstance方法后创建对象,这种现象叫做对象的延迟加载。如代码示例-2

代码示例-2
class Single
{
	private static Single s = null;
	private Single(){}
	public static Single getInstance()
	{
		if(s==null)
			s = new Single();
		return s;
	}
}
但是懒汉式,在多线程中会出现安全问题。假设A,B两个线程并发访问getInstacne()方法,因为有多条语句操作共享数据s,一个在判断另一个在赋值。当线程A判断为null,此

时A线程假设遇到sleep语句睡了一会。被线程B抢到执行权,线程B进来也sleep了,A醒后创建一个对象赋给s,(if语句只判断一次)B醒后向下执行,又创建个对象。单例设计模

式的目的要保证一个类在内存中对象的唯一性,new了很多对象,所以不安全。此时想到了同步,将getInstance()函数变为同步函数,这样A线程进来后,B线程就进不来。所

以当A线程new一个对象赋给s出去后,B进来判断s不为null,就不new对象,直接返回s使用。这样就解决了安全问题,如代码示例-3

代码示例-3

class Single
{
	private static Single s = null;
	private Single(){}
	public static synchronized Single getInstance()
	{
		if(s==null)
			s = new Single();
		return s;
	}
}
但是又考虑到,如果有n多线程并发访问getInstance()方法想获取实例,每次调用都要判断锁,判断锁的次数会非常多,导致代码运行速度降低。为了解决这个问题,采用双重

判断的方式,当A线程进来后,先判断s是否为空,如果为空在持有锁后可能sleep一会,B线程没有持有锁,不能进来A线程醒后,new一个对象出去释放锁,B线程持有锁来,

判断st不为null,直接使用s,以后其他所有线程调用getInstance()方法,判断s不为空,就直接使用s,这种方式锁只判断了一次,解决了程序运行低的问题。如代码示例-4

代码示例-4
class Single
{
	private static Single s = null;
	private Single(){}
	public static Single getInstance()
	{
		if(s==null)
		{
			synchronized(Single.class)
			{
				if(s==null)
					s = new Single();		
			}
		}
		return s;
	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值