Java设计模式之单例(Singleton)模式解析

一,缘由

暑假就要去实习了,有点慌张。以前学Java时有许多重要的知识点都存在doc文档,心想什么时候有时间就写到博客里,结果可想而知,文档全都归西了,今年才开始静的下心来写博客。好吧,既然那些文档不见了,那就隔几天写一篇博客,就当是重温自己的Java之路吧。既然是重温Java,首当其冲的当然就是设计模式了。那么就从Java单例模式开始吧。

二,单例模式的分类

有没搞错,单例模式还有分类?还真有,单例模式按其特点来分就有两种,一是饿汉模式,另一种就是懒汉模式。

三,单例模式之饿汉模式

饿汉模式的特点:只要类一加载,就会创建对象。贴一段代码吧,不然不太好描述,嘻嘻!

package com.bighuan.singleton;

/**
 * 单例模式之饿汉式 
 * 	特点:类一加载就创建对象
 * 
 * @author bighuan JDK中的单例体现:Runtime runtime=Runtime.getRuntime();
 */
public class SingletonPad {

	private static SingletonPad mInstance = new SingletonPad();

	// 把构造方法私有是为了不让外界随意创建
	private SingletonPad() {

	}

	public static SingletonPad getInstance() {

		return mInstance;
	}

	public void show() {
		System.out.println("卖平板1了...");
	}

}

不管是哪种单例模式,都是为了只有一个实例对象,对象不能被外界随意创建。所以就把构造方法私有private了,只能在该类内部new对象。并且在类被加载的时候就创建了一个对象(mInstance用static修饰了),该对象是私有的就保证mInstance不会被别人置为null,若没有private修饰,就有可能发生SingletonPad.mInstace=null,那就尴尬了。程序内提供了一个静态的getInstance()公共方法,以便获得SingletonPad对象。至于为什么叫做饿汉模式,那是因为这个SingletonPad类只要被加载了,就会创建一个对象,就像饿汉一样,什么都吃。如果我们用不到这个对象,那就浪费了资源了,因为多创建了对象啊。所以,就有了单例模式之懒汉模式。

四,单例模式之懒汉模式

懒汉模式的特点:什么时候用就什么时候创建对象。不多说,贴代码再解释。

package com.bighuan.singleton;

/**
 * 设计模式之懒汉式
 * 	特点:什么时候用就什么时候创建
 * 
 * @author bighuan
 * 
 */
public class SingletonPad2 {

	private volatile static SingletonPad2 mInstance = null;

	private SingletonPad2() {

	}

	/**
	 * 如果不加锁,则会有线程安全问题
	 * 
	 * @return
	 */
	public static SingletonPad2 getInstance() {
		// 双重锁定(Double-Check Locking),第一次创建对象时会受到同步锁的影响,但只要创建过一次,就不会再受到同步锁的影响了。
		if (mInstance == null) {
			synchronized (SingletonPad2.class) {
				if (mInstance == null) {
					mInstance = new SingletonPad2();
				}
			}
		}

		return mInstance;
	}

	public void show() {
		System.out.println("卖平板2了...");
	}

}

懒汉模式和饿汉模式的区别就是,懒汉模式不会再加载类的时候就创建一个对象,而是什么时候要用什么时候就创建。并且,特别要注意的是,如果懒汉模式的getInstance()方法内部不加锁的话,是会有线程安全问题的(注意看我代码中的注释)。当然了,同步锁也可以加在getInstance()方法上,但那样就会影响性能,因为那样的话每次调用那个方法都会受到同步锁的影响,从而影响效率。所以在方法内部加锁就足够了,同步锁最多只会使用一次。

另外,需要注意的时,我们在声明mInstace时使用了一个volatile关键字。volatile是一个类型修饰符,volatile用来修饰被不同线程访问和修改的变量。如果我们在懒汉模式中不加这个关键字,是有问题的。具体原因我就不解释了,看客就自行百度了。

五,测试

很简单,看代码及结果:

package com.bighuan.singleton;

/**
 * 测试单例模式
 * 
 * @author bighuan
 * 
 */
public class SingletonTest {

	public static void main(String[] args) {
		// 测试单例模式之饿汉模式
		SingletonPad pad1 = SingletonPad.getInstance();

		SingletonPad pad2 = SingletonPad.getInstance();
		pad1.show();
		pad2.show();
		System.out.println(pad1 == pad2);

		System.out.println("------------");

		// 测试单例模式之懒汉汉模式
		SingletonPad2 p1 = SingletonPad2.getInstance();

		SingletonPad2 p2 = SingletonPad2.getInstance();

		p1.show();
		p2.show();
		System.out.println(p1 == p2);

	}

}

运行结果如下:

卖平板1了...
卖平板1了...
true
------------
卖平板2了...
卖平板2了...
true

确实只有一个对象吧,哈哈!

六,总结

面试时考官喜欢在懒汉模式的线程安全问题上做文章,但只要理解了单例模式,就完全没问题的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值