dom4j中的单例策略
单例模式的实现方法有很多,饿汉和饱汉 ,Double-check Locking的模式,? Registry of Singleton 模式
这里介绍下单例策略
在dom4j中就生成DocumentFactory工厂单例的时候就有单例策略的使用。
?
?
?
策略的介面如下:
public interface SingletonStrategy { /** * return a singleton instance of the class specified in setSingletonClass */ Object instance(); /** * reset the instance to a new instance for the implemented strategy */ void reset(); void setSingletonClassName(String singletonClassName);}?
策略的两个实作:
1、
public class SimpleSingleton implements SingletonStrategy {//singletonClassName 需要被实例化成单例的类名,在DocumentFactory 中通过配置文件传值 private String singletonClassName = null;//singletonInstance 通过 reset() 返回单例的实例对象 private Object singletonInstance = null; public SimpleSingleton() { }//只是返回实例的对象方法 public Object instance() { return singletonInstance; }//used by setSingletonClassName() 产生不同的单例实例对象 public void reset() { if (singletonClassName != null) { Class clazz = null; try { clazz = Thread.currentThread().getContextClassLoader().loadClass( singletonClassName); singletonInstance = clazz.newInstance(); } catch (Exception ignore) { try { clazz = Class.forName(singletonClassName); singletonInstance = clazz.newInstance(); } catch (Exception ignore2) { } } } }//传进去singletonClassName 生成 一个实例 ,通过instance()取得单例 public void setSingletonClassName(String singletonClassName) { this.singletonClassName = singletonClassName; reset(); }}?
?
?
2、每个线程一个单例实例对象,没这么用过不知道一般用在什么地方
public class PerThreadSingleton implements SingletonStrategy { private String singletonClassName = null; private ThreadLocal perThreadCache = new ThreadLocal(); public PerThreadSingleton() { }//重置每个线程的单例对象 public void reset() { perThreadCache = new ThreadLocal(); }// public Object instance() { Object singletonInstancePerThread = null; // use weak reference to prevent cyclic reference during GC WeakReference ref = (WeakReference) perThreadCache.get(); // singletonInstancePerThread=perThreadCache.get(); // if (singletonInstancePerThread==null) { if (ref == null || ref.get() == null) { Class clazz = null; try { clazz = Thread.currentThread().getContextClassLoader().loadClass( singletonClassName); singletonInstancePerThread = clazz.newInstance(); } catch (Exception ignore) { try { clazz = Class.forName(singletonClassName); singletonInstancePerThread = clazz.newInstance(); } catch (Exception ignore2) { } } perThreadCache.set(new WeakReference(singletonInstancePerThread)); } else { singletonInstancePerThread = ref.get(); } return singletonInstancePerThread; } public void setSingletonClassName(String singletonClassName) { this.singletonClassName = singletonClassName; }}?
3、需要实现的单例类
?
public class DocumentFactory implements Serializable {//关联一个单例策略对象 private static SingletonStrategy singleton = null; protected transient QNameCache cache; /** Default namespace prefix -> URI mappings for XPath expressions to use */ private Map xpathNamespaceURIs;// used by getInstance() 创建单例策略对象 并将DocumentFactory 的classname set 给它 ,返回单例策略对象 private static SingletonStrategy createSingleton() { SingletonStrategy result = null; //通过配置文件得到DocumentFactory 的classname String documentFactoryClassName; try { documentFactoryClassName = System.getProperty("org.dom4j.factory", "org.dom4j.DocumentFactory"); } catch (Exception e) { documentFactoryClassName = "org.dom4j.DocumentFactory"; } try { String singletonClass = System.getProperty( "org.dom4j.DocumentFactory.singleton.strategy", "org.dom4j.util.SimpleSingleton"); Class clazz = Class.forName(singletonClass); result = (SingletonStrategy) clazz.newInstance(); } catch (Exception e) { result = new SimpleSingleton(); } result.setSingletonClassName(documentFactoryClassName); return result; } public DocumentFactory() { init(); } /** * <p> * Access to singleton implementation of DocumentFactory which is used if no * DocumentFactory is specified when building using the standard builders. * </p> * * @return the default singleon instance *///DocumentFactory 创建自己的方法 线程安全的 public static synchronized DocumentFactory getInstance() { if (singleton == null) { singleton = createSingleton(); } return (DocumentFactory) singleton.instance(); }?
?