漫谈设计模式(二):单例(Singleton)模式

1.前言

实际业务中,大多业务类只需要一个对象就能完成所有工作,另外再创建其他对象就显得浪费内存空间了。这时便要用到单例模式,就如其名一样,此模式让一个类只能生成唯一的一个对象。而单例模式,根据此唯一的单例创建的时机不同,可以分为懒汉模式和饿汉模式。

2.饿汉(单例)模式

public class HungrySingleton {
     //声明一个当前类的变量为类变量,方便静态方法访问,保证还存在一个当前类的对象
	private static LazySingleton singleInstance = new LazySingleton(); 
	private String description; //其他属性

	/*
	 * 私有化唯一的默认构造方法,使其不能在外部(其他类中)通过构造方法创建实例对象
	 */
	private LazySingleton() {}  

	/**
	 * 返回唯一的实例对象
	 * @return
	 */
	/*
	 * 因构造器被私有化,外部不能直接获得实例对象,也就不能调用实例方法获得对象的引用
	 * (这也就陷入了死循环。外部起初没有持有singleInstance的引用,现实需求又想通过此对象来调用方法获得它的引用,
	 * 另外若外部本来持有它的引用,就根本用不着调用方法来获得它的引用。)
	 * 因此只能将此方法声明为与对象无关的静态方法,静态方法又不能直接访问成员变量,singleInstance只能声明为静态的类变量
	 */
	public static LazySingleton getInstance() {
		return singleInstance;
	}

}

 

3.懒汉(单例)模式

public class LazySingleton {
	// 用"volatile"关键字声明,防止编译优化,改变内存分配顺序
	private static volatile LazySingleton singleInstance = null;
	// 类元锁
	private static final Class<?> CLASS_LOCK = LazySingleton.class;
	
	//对象计数器
	private static  int instanceCount=0;

	private LazySingleton() {
	}

	/**
	 *  返回此类的唯一对象
	 * @return
	 */
	public static LazySingleton getInstance() {
		/*
		 * 设置同步块,保证在多线程条件下,也只有一个对象(单线程下,不需要同步)
		 * 
		 * 只有检测到singleInstance未被实例化时,才设置同步块。
		 * 如果检测到singleInstance已被实例化,则直接返回其引用。
		 * 这种双重同步验证锁,比给整个方法中的代码设为同步块或将方法声明为同步方法,性能要高得多。
		 * 因为双重同步验证,只会同步一次,其另外两种思路一直都需要同步。
		 * 
		 */
		if (singleInstance == null) {
			synchronized (CLASS_LOCK) {
				if (singleInstance == null) {
					singleInstance = new LazySingleton();
					instanceCount++;
				}
			}
		}
		return singleInstance;
	}
}

  

 

猜你喜欢

转载自www.cnblogs.com/gocode/p/singleton-pattern.html