Java面试知识点(二十)单例模式之懒汉式和饿汉式

单件模式用途:
单件模式属于工厂模式的特例,只是它不需要输入参数并且始终返回同一对象的引用。
单件模式能够保证某一类型对象在系统中的唯一性,即某类在系统中只有一个实例。它的用途十分广泛,打个比方,我们开发了一个简单的留言板,用户的每一次留言都要将留言信息写入到数据库中,最直观的方法是没次写入都建立一个数据库的链接。这是个简单的方法,在不考虑并发的时候这也是个不错的选择。但实际上,一个网站是并发的,并且有可能是存在大量并发操作的。如果我们对每次写入都创建一个数据库连接,那么很容易的系统会出现瓶颈,系统的精力将会很多的放在维护链接上而非直接查询操作上。这显然是不可取的。
如果我们能够保证系统中自始至终只有唯一一个数据库连接对象,显然我们会节省很多内存开销和 cpu 利用率。这就是单件模式的用途。

下面对单件模式的懒汉式与饿汉式进行简单介绍:
1、饿汉式:在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。
2、懒汉式:当程序第一次访问单件模式实例时才进行创建。

如何选择:
如果单件模式实例在系统中经常会被用到,饿汉式是一个不错的选择。
反之如果单件模式在系统中会很少用到或者几乎不会用到,那么懒汉式是一个不错的选择。

//饿汉式单例模式
class Singleton{
	//私有的构造函数,保证外类不能实例化本类
	private Singleton(){}
	//自己创建一个类的实例化
	private static Singleton singleton = new Singleton();
	//创建一个get方法,返回一个实例s
	public static Singleton getInstance(){
		return singleton;
	}

//懒汉式单例模式
class Singleton {
	// 私有的构造函数,保证外类不能实例化本类
	private Singleton() {
	}
 
	// 自己创建一个类的实例化
	private static Singleton singleton;
 
	// 创建一个get方法,返回一个实例s
	public static Singleton getInstance(){
		//判断singleton是否为null,如果为null,即判定需要实例化
		if (singleton == null) {
			singleton = new Singleton();
		}
		return singleton;
	}
}

懒汉式在多线程中是不支持的,所以相对来说,更多的是用饿汉式
比如,现在有 A 线程和 B 线程,A 线程刚好在这个 getInstance()方法中,刚刚判断完非空(此时为 null),即需要创建实例,然而,就是这么巧,B 线程抢到了 CPU 的执行权,A 线程 sleep 了,这时,B 线程也进行了这个判断,和 A 一样,都需要创建实例,而这时,A 也抢到了 CPU,这时,B 就 sleep 了,然后 A 执行了实例化后,B 又抢到 CPU 执行权,然后 B 也实例化,这时,出现问题了,A 和 B 都实例化了一个对象,这就是赤果果的两个对象呀,单例呢,唯一呢,全都没了。

你可能感兴趣的:(java,面试,Java面试知识汇总)