设计模式--单例模式的探究
从360doc中截取下来的关于单例模式的分析,感觉不错,本着“不重复发明轮子的思想”我就采取了拿来主义,对格式稍加改造(符合iteye的发表格式。。。)粘贴至此。
作为对象的创建模式[GOF95],单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。由定义可以总结出单例模式的要点有三个:一是单例类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
虽然从类图上看,单例模式是最简单的设计模式之一,但是真正正确地使用单例模式却不是那么简单的事。
首先看一个经典的单例实现。
public class Singleton { private static Singleton uniqueInstance = null; private Singleton() { // Exists only to defeat instantiation. } 』 public static Singleton getInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; }// Other methods...}
public class Singleton { private static Singleton uniqueInstance = new Singleton();private Singleton() {// Exists only to defeat instantiation.} public static Singleton getInstance() {return uniqueInstance;}// other methods...}
public class Singleton { private static Singleton uniqueInstance = null; private Singleton() { // Exists only to defeat instantiation. }public synchronized static Singleton getInstance() { if (uniqueInstance == null) {uniqueInstance = new Singleton();} return uniqueInstance;}//Other methods...}
public class Singleton { // volatile is very important for uniqueInstance consistency. private volatile static Singleton uniqueInstance = null; private Singleton() { // Exists only to defeat instantiation. } public static Singleton getInstance() { // first check no need to synchronize. if (uniqueInstance == null) { // second check need to synchronize, but only run limit times. synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } // Other methods...}
public class Singleton { // an inner class holder the uniqueInstance. private static class SingletonHolder { static final Singleton uniqueInstance = new Singleton(); } private Singleton() { // Exists only to defeat instantiation. } public static Singleton getInstance() { return SingletonHolder.uniqueInstance; } // Other methods...}
public class RegSingleton { static private HashMap m_registry = new HashMap(); static { RegSingleton x = new RegSingleton(); m_registry.put(x.getClass().getName(), x); } protected RegSingleton() { } public static RegSingleton getInstance(String name) { if (name == null) { name = "com.javapatterns.singleton.demos.RegSingleton"; } if (m_registry.get(name) == null) { try { m_registry.put(name, Class.forName(name).newInstance()); } catch (ClassNotFoundException cnf) { System.out.println("Couldn't find class " + name); } catch (InstantiationException ie) { System.out.println("Couldn't instantiate an object of type "+ name); } catch (IllegalAccessException ia) { System.out.println("Couldn't access class " + name); } } return (RegSingleton) (m_registry.get(name));}}// sub-class implements RegSingleton.public class RegSingletonChild extends RegSingleton { public RegSingletonChild() { } static public RegSingletonChild getInstance() { return (RegSingletonChild) RegSingleton .getInstance("com.javapatterns.singleton.demos.RegSingletonChild"); } public String about() { return "Hello, I am RegSingletonChild."; }}
private static Class getClass(String classname) throws ClassNotFoundException { ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); if (classLoader == null) classLoader = Singleton.class.getClassLoader(); return (classLoader.loadClass(classname));}
public class Singleton implements java.io.Serializable { public static Singleton INSTANCE = new Singleton(); protected Singleton() { // Exists only to thwart instantiation. } private Object readResolve() { return INSTANCE; }}
import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.cfg.Configuration; public class HibernateSessionFactory { private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; private static final ThreadLocal threadLocal = new ThreadLocal(); private static Configuration configuration = new Configuration(); private static org.hibernate.SessionFactory sessionFactory; private static String configFile = CONFIG_FILE_LOCATION; static { try { configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } private HibernateSessionFactory() { } public static Session getSession() throws HibernateException { Session session = (Session) threadLocal.get(); if (session == null || !session.isOpen()) { if (sessionFactory == null) { rebuildSessionFactory(); } session = (sessionFactory != null) ? sessionFactory.openSession() : null; threadLocal.set(session); } return session; }// Other methods...}