黑马程序员——单例设计模式

单例设计模式确保一个类只有一个实例,并提供全局访问点。本文介绍了单例模式的概念、实现步骤,以及两种常见的实现方式:饿汉式和懒汉式。重点讨论了饿汉式的简洁与安全性,以及懒汉式在多线程环境下可能存在的问题。推荐在实际开发中使用饿汉式来实现单例。
摘要由CSDN通过智能技术生成

-----------android培训java培训、java学习型技术博客、期待与您交流!------------                                                                                                                

   单例设计模式

单例设计模式:产生一个类,并保证这个类在内存中只存在一个对象。

思想:保证对象唯一。也就是被创建的所有该类对象在内存中的地址唯一。

   属于这个类的所有变量(引用)都指向一个同一个地址。换句话来说就是这种

           对象在内存中只有一个,只是在应用是可能有多个名字(变量)与之对应。

1、避免其他程序多次建立该类对象,必须先禁止其他程序建立该类对象。

2、要让其他程序可以访问到该类对象,只有在本类中自定义一个自身的对象。

3、使其他程序可以对自定义对象进行访问,就必须对外提供一些访问方式。


与思想对应的实现步骤:

1、将构造函数私有化。

2、在类中创建一个本类对象。

3、提供一个方法可以获取到该对象。


应用方式:

对事物该怎么描述,还是怎么描述。

当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。


关键部分代码实现:

单例设计模式第一种表现形式(饿汉式),先初始化对象。

Single类一进内存,就已经创建好。

class Single
{
	private Single(){}   //构造函数私有化
	
	private static Single s = new Single(); //创建自身对象
	
	public static Single getInstance()      //调用自身对象的成员方法
	{
		return s;
	}

}
public class SingleDemo {

	public static void main(String[] args) 
	{
		Single ss = Single.getInstance();
	}

}

单例设计模式的第二种表现形式(懒汉式),对象延时加载。

Single类进内存,对象还没有存在,只有调用getInstance方法时,才建立对象。

class Single
{
	private static Single s = null;
	private Single(){}
	public static Single getInstance()
	{
		if(s==null)
			s = new Single();
		return s;
	}
}


代码测试:

class Single
{
	private int num;
	public void setNum(int num)
	{
		this.num = num;
	}
	public int getNum()
	{
		return num;
	}
	
	private Single(){}   //构造函数私有化
	
	private static Single s = new Single(); //创建自身对象
	
	public static Single getInstance()      //调用自身对象的成员方法
	{
		return s;
	}

}
public class SingleDemo {

	public static void main(String[] args) 
	{
		Single s1 = Single.getInstance();
		Single s2 = Single.getInstance();
		
		s1.setNum(23);
		
		System.out.println(s2.getNum());
	}

}

控制台打印的运行结果:23

原因:Single类存在s、s1、s2三个引用,都指向同一个Single对象。


开发一般用饿汉式,因为其简单、安全。

在应用多线程时,懒汉式容易出现出现创建多个Single类对象的问题

如下所示:

class Single
{
	private static Single s = null;
	private Single(){}
	public static Single getInstance()
	{
		if(s==null)
			//-->等待  这个地方可能会有多个线程进入,也就创建了多个Single对象。
			s = new Single();
		return s;
	}
}
使用synchronized关键字可以解决这个问题。

如下所示:

class Single
{
	private static Single s = null;
	private Single(){}
	public static synchronized Single getInstance()
	{
		if(s==null)
			//-->等待  这个地方可能会有多个线程进入,也就创建了多个Single对象。
			s = new Single();
		return s;
	}
}
synchronized关键字修饰的方法只允许一个线程进入,其他线程要进入时必须先判断这个方法有没有线程在调用。这样就降低了程序的性能。
改良型解决方案:

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;
	}
}

利用双层判断减少getInstance方法运行时锁的判断次数。

总之,开发时定义单例设计模式时,建议使用饿汉式。


-----------android培训java培训、java学习型技术博客、期待与您交流!------------ 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值