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; }
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; } }
四.使用场景
系统只需要拥有一个的全局对象。比喻线程池,日志对象等等。
五.单例的演变