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();
    }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章