设计模式学习七:单例模式

chvnetcom 2012-02-20

一.概念

     确保一个类只有一个实例,并提供一个全局访问点来获取该实例。

二.UML

设计模式学习七:单例模式

三.三种单例模式

  • 饿汉模式:在类加载的时候就实例化一个自己的对象。
package com.zzy.singleton;
/**
 * 饿汉模式
 * @author eason
 *
 */
public class Singleton {
	//JVM在静态初始块中创建对象
	//保证了在任何线程访问singleton变量之前,一定先创建此实
	//保证了线程安全
	//static确保Singleton类只有一个实例
	//保证了单例
	private static Singleton singleton = new Singleton();
	
	//private构造函数,只能在该类内部使用
	private Singleton(){
	}
	
	public static Singleton getInstance() {
		return singleton;
	}
	
}
  • 懒汉模式:在实例第一次被引用时才将自己实例化
package com.zzy.singleton;
/**
 * 懒汉模式
 * @author eason
 *
 */
public class Singleton {
	//static确保Singleton类只有一个实例
	//保证了单例
	private static Singleton singleton = null;
	
	//private构造函数,只能在该类内部使用
	private Singleton(){
	}
	
	//synchronized确保每个线程在进入getInstance方法前
	//要先等到别的线程离开该方法
	//也就是说,最极端的情况时也不会有两个线程同时进入该方法,不会 new Singleton()两次
	//保证了线程安全
	public static synchronized Singleton getInstance() {
		if(singleton == null) {
			singleton = new Singleton();
		}
		return singleton;
	}
  • 双重检查模式:相比懒汉模式中的每次调用getInstance方法都需要同步,双重检查模式只有第一次调用getInstance方法才会进入此同步块
package com.zzy.singleton;
/**
 * 双重检查模式
 * @author eason
 *
 */
public class Singleton {
	//static确保Singleton类只有一个实例
	//保证了单例
	//volatile确保当singleton被初始化成Singleton实例时
	//多个线程正确处理singleton变量
	private volatile static Singleton singleton = null;
	
	//private构造函数,只能在该类内部使用
	private Singleton(){
	}
	
	public static Singleton getInstance() {
		//如果实例不为空,进入同步区
		if(singleton == null) {
			//只有第一次调用getInstance方法才会进入此同步块
			synchronized (Singleton.class) {
				//为什么这里还要检查一次???因为可能多个线程同时进入上一个if判断里面
				if(singleton == null) {
					singleton = new Singleton();
				}
			}
		}
		return singleton;
	}
	
}

四.使用场景

     系统只需要拥有一个的全局对象。比喻线程池,日志对象等等。

五.单例的演变

设计模式学习七:单例模式

相关推荐